请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于Promise.all的问题

MyPromise.promiseAll = function(promises){
	return new Promise((resolve, reject)=>{
		if(!Array.isArray(promises)) throw new TypeError('promises is not a iterable')
		let resolvedCounter = 0
		let resolvedResult = []
		promises.forEach((p)=>{
			p.then(value => {
				resolvedCounter++
				resolvedResult.push(value)
				if(resolvedCounter === promises.length){
					return resolve(resolvedResult)
				}
			},reason => {
				return reject(reason)
			})
		})
	})
}

.push会导致返回结果数组的顺序错误

let p1 = Promise.resolve(1)
let p2 = Promise.resolve(2)
let a = Promise.promiseAll([p1,new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(3)
    },3000)
}),p2])
// 输出
[1,2,3]

正在回答 回答被采纳积分+3

5回答

前端祭酒师 2022-05-05 04:08:50
  //   等待所有promise有结果
  static all(promiseList = []) {
  // 使用类数组的方案 手动控制length的长度 更加细粒度
    let result = {
      length: 0,
    };
    let length = promiseList.length;

    return new MyPromise((resolve, reject) => {
      promiseList.forEach((promiseItm, index) => {
        promiseItm.then((res) => {
          result[index] = res;
          result.length++;
          if (length === result.length) {
            resolve(Array.from(result));
          }
        });
      });
    });
  }


1 回复 有任何疑惑可以回复我~
  • 使用类数组 更细粒度的 手动控制length 返回的时候 Array.from()转化为数组
    回复 有任何疑惑可以回复我~ 2022-05-05 04:10:30
zcj2022 2022-04-24 22:10:00

使用没let以前的方式,形成块级作用域来解决因为等待时间不同,导致返回值数组不能和传入的promise数组对应的问题

static all(promiseList = []) {
  const p1 = new MyPromise((resolve, reject) => {
    const result = [];
    const length = promiseList.length;
    let resolveCount = 0;

    promiseList.forEach((p, index) => {
      (function (index) { // 形成块级作用域
        p.then((res) => {
          result[index] = res;
          resolveCount++;
          if (resolveCount === length) {
            resolve(result);
          }
        }).catch((err) => reject(err));
      })(index);
    });
  });

  return p1;
}


0 回复 有任何疑惑可以回复我~
Tao_53755083 2022-03-21 13:23:01
MyPromise.all = function (list) {
  return new MyPromise((resolve, reject) => {
    const length = list.length
    const result = []
    let nub = 0

    list.forEach((p, i) => {
      p.then(data => {
	    nub++
        result[i] = data // 这里用下标存储 确保输入与输出 顺序一致
        
        if (nub === length) {
          resolve(result)
        }
      }).catch(err => {
        reject(err)
      })
    })
  })
 }

用下标就可以解决这个问题


0 回复 有任何疑惑可以回复我~
  • 应该不行吧,.then的执行是异步的,索引 i 是同步变化,i会在短时间内快速变成最大值length-1,你这样写会导致 data 每次存的都是 result[length-1]
    回复 有任何疑惑可以回复我~ 2023-02-09 16:02:19
weixin_慕神0153302 2022-03-20 14:38:14

...

0 回复 有任何疑惑可以回复我~
双越 2022-03-09 21:47:35

好问题。我考虑下这里怎么优化。


0 回复 有任何疑惑可以回复我~
  • emmm,是的,面试官问到我这了,emmm
    回复 有任何疑惑可以回复我~ 2022-03-10 00:17:14
  • 使用类数组 更细粒度的 手动控制length 返回的时候 Array.from()转化为数组
    回复 有任何疑惑可以回复我~ 2022-05-05 04:06:28
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信