Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Promise 相关面试题 #45

Open
conan1992 opened this issue Jul 3, 2020 · 0 comments
Open

Promise 相关面试题 #45

conan1992 opened this issue Jul 3, 2020 · 0 comments

Comments

@conan1992
Copy link
Owner

conan1992 commented Jul 3, 2020

使用Promise实现每隔1秒输出1,2,3

[1,2,3].reduce((acc, cur) => {
	return acc.then(resolve => {
		return new Promise(resolve =>{
			setTimeout(() =>{
				console.log(cur);
				resolve()
			}, 1000)
		})
	})
}, Promise.resolve())

使用Promise实现红绿灯交替重复亮

红灯3秒亮一次,黄灯2秒亮一次,绿灯1秒亮一次;如何让三个灯不断交替重复亮灯?(用Promise实现)三个亮灯函数已经存在

function red() {
	console.log('red');
}
function green() {
	console.log('green');
}
function yellow() {
	console.log('yellow');
}
  • promise
function light(fn, timerout){
	return new Promise(resolve => {
		setTimeout(function(){
			fn();
			resolve();
		}, timerout)
	})
}
function setp(){
	Promise.resolve().then(resolve => {
		return light(red, 3000)
	}).then(resolve => {
		return light(yellow, 2000)
	}).then(resolve => {
		return light(green, 1000)
	}).then(resolve => {
		setp();
	})
}
setp()
  • 不用promise
var arr = [{
	timeout: 3000,
	fun: red
},{
	timeout: 2000,
	fun: yellow
},{
	timeout: 1000,
	fun: green
}];
var num = 0;
function setp(){
	
	setTimeout(function(fn){
		fn();
		num++
		setp();
	}, arr[(num)%3].timeout, arr[(num)%3].fun)
}
setp();

封装一个异步加载图片的方法

function loadImg(url) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = function() {
      console.log("一张图片加载完成");
      resolve(img);
    };
    img.onerror = function() {
    	reject(new Error('Could not load image at' + url));
    };
    img.src = url;
  });

限制异步操作的并发个数并尽可能快的完成全部

有8个图片资源的url,已经存储在数组urls中。
urls类似于['https://image1.png', 'https://image2.png', ....]
而且已经有一个函数function loadImg,输入一个url链接,返回一个Promise,该Promise在图片下载完成的时候resolve,下载失败则reject。
但有一个要求,任何时刻同时下载的链接数量不可以超过3个。
请写一段代码实现这个需求,要求尽可能快速地将所有图片下载完成。

function limitLoad(urls, handler, limit) {
  let sequence = [].concat(urls); // 复制urls
  // 这一步是为了初始化 promises 这个"容器"
  let promises = sequence.splice(0, limit).map((url, index) => {
    return handler(url).then(() => {
      // 返回下标是为了知道数组中是哪一项最先完成
      return index;
    });
  });
  // 注意这里要将整个变量过程返回,这样得到的就是一个Promise,可以在外面链式调用
  return sequence
    .reduce((pCollect, url) => {
      return pCollect
        .then(() => {
          return Promise.race(promises); // 返回已经完成的下标
        })
        .then(fastestIndex => { // 获取到已经完成的下标
        	// 将"容器"内已经完成的那一项替换
          promises[fastestIndex] = handler(url).then(
            () => {
              return fastestIndex; // 要继续将这个下标返回,以便下一次变量
            }
          );
        })
        .catch(err => {
          console.error(err);
        });
    }, Promise.resolve()) // 初始化传入
    .then(() => { // 最后三个用.all来调用
      return Promise.all(promises);
    });
}
limitLoad(urls, loadImg, 3)
  .then(res => {
    console.log("图片全部加载完毕");
    console.log(res);
  })
  .catch(err => {
    console.error(err);
  });

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant