第 89 题:设计并实现 Promise.race()

发布于 2022-07-17 11:22:45 字数 320 浏览 169 评论 20

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个 promise 解决或拒绝,返回的 promise 就会解决或拒绝。更多介绍:https://www.wenjiangs.com/wiki/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/race

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

伴我心暖 2022-05-04 13:55:53
function promiseRace(promiseArr) {
  return new Promise((resolve,reject) => {
    for(let i = 0;i < promiseArr.length;i++) {
      promiseArr[i].then(res => resolve(res),rej => reject(rej))
    }
  })
}

const pro1 = new Promise((res,rej) => {
  setTimeout(() => {
    res('我是1')
  },1000)
})

const pro2 = new Promise((res,rej) => {
  setTimeout(() => {
    res('我是2')
  },10000)
})

const pro3 = new Promise((res,rej) => {
  setTimeout(() => {
    res('我是3')
  },300)
})

const race = promiseRace([pro1,pro2,pro3])
race.then(res => {
  console.log(res)
})
请持续率性 2022-05-04 13:55:53
let p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('success')
    }, 100)
})
let p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject('failed')
    }, 500)
})

/**
 * 实现一个race
 * @param {Array} array 
 */
let race = function (array) {
    return new Promise((resolve, reject) => {
        let len = array.length;
        while (len--) {
            array[len].then(res => {
                return resolve(res);
            }).catch(err => {
                return reject(err);
            })
        }
    })
}
// 调用
race([p1, p2]).then(res => {
    console.log(res);
}).catch(err => {
    console.error(err);
})

resolve()前 没必要return 吧

如梦亦如幻 2022-05-04 13:55:53
function promiseRace(promises) {
    return new Promise((res, rej) => {
        promises.forEach(promise => promise.then(res).catch(rej));
    })
}
木森分化 2022-05-04 13:55:53
Promise.protopype.race = (promises) => {
    return new Promise((resolve, reject) => {
        promises.forEach(promise => promise.then(resolve, reject))
    });
}
笑看君怀她人 2022-05-04 13:55:53
	static race(arr) {
		// 只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。
		return new PromiseA((resolve, reject) => {
			arr.forEach((item)=>{
				// “状态的变更是单向的”
				item.then(resolve, reject);
			})
		})
	}
や莫失莫忘 2022-05-04 13:55:53

有点像电路的并行,只要有一个开关打开的就可以接通了。

看轻我的陪伴 2022-05-04 13:55:53
Promise.race = function(promises){
    return new Promise((resolve, reject)=>{
        for(let i of promises){
            Promise.resolve(i).then(resolve, reject)
        }
    })    
}
夜声。 2022-05-04 13:55:53
function testRace() {
    function getPromise(i, timeout = 0) {
        const random = Math.random();
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                random > 0.5 ? reject(`reject: ${random} - ${i}`) : resolve(`resolve: ${random} - ${i}`)
            }, timeout)
        })
    }

   
    Promise.race2 = function (promises) {
        return new Promise((resolve, reject) => {
            for (let i = 0; i < promises.length; i++) {
                // promises[i] 可能是普通值
                Promise.resolve(promises[i]).then((data) => {
                    resolve(data);
                }, (err) => {
                    reject(err)
                });
            }
        });
    }


    const p1 = getPromise(1, 200);
    const p2 = getPromise(2, 300);
    const p3 = getPromise(3, 100);

    Promise.race([p1, p2, p3])
        .then((res) => {
            console.log('res:', res)
        })
        .catch((err) => {
            console.log('err:', err);
        })

    Promise.race2([p1, p2, p3])
        .then((res) => {
            console.log('res:', res)
        })
        .catch((err) => {
            console.log('err:', err);
        })
}

testRace();

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。

可以通过设置 getPromise 函数的第二个参数,验证race2 输出结果与 race是否一致

℉服软 2022-05-04 13:55:53
Promise._race = function(iterator) {
            return new Promise((resolve, reject) => {
                for (let item of iterator) {
                    Promise.resolve(item).then((data) => {
                        resolve(data);
                    }).catch(err => {
                        reject(err);
                    });
                }
            });
        }
不及他 2022-05-04 13:55:53

Tip:

  1. Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个 promise 解决或拒绝,返回的 promise 就会解决或拒绝
  1. 判断函数参数是否是可迭代的(很多答案都忽略了)
const isIterable = (data, reject) => {
  const type = typeof data;
  if (!data[Symbol.iterator]) {
    if (reject) {
      reject(
        new TypeError(
          `${type} ${data} is not iterable (cannot read property Symbol(Symbol.iterator))`
        )
      );
    } else {
      throw new TypeError(
        `${type} ${data} is not iterable (cannot read property Symbol(Symbol.iterator))`
      );
    }
  }
};
Promise.myRace = function (promises) {
  return new Promise((resolve, reject) => {
    isIterable(promises, reject); // 判断是否是迭代对象
    const promiseArray = [...promises];
    promiseArray.forEach((pr) => {
      if (!(pr instanceof Promise)) {
        pr = Promise.resolve(pr);
      }
      pr.then(resolve, reject);
    });
  });
};

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, "one");
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(reject, 100, "two");
});

Promise.myRace([promise1, promise2])
  .then((value) => {
    console.log("value", value);
    // Both resolve, but promise2 is faster
  })
  .catch((err) => {
    console.log("err", err);
  });
茶花眉 2022-05-04 13:55:53
Promise.race = function(values){
  return new Promise((resolve,reject)=>{
    for(let i = 0 ; i< values.length;i++){
      Promise.resolve(values[i]).then(resolve,reject)
    }
  })
}
傲娇萝莉攻 2022-05-04 13:55:52
Promise.race = function(...list) {
  return new Promise((resolve, reject) => {
    for (let item of list) {
      let p = item.then ? p : Promise.resolve(p) 
      // p.then(value => {
      //   resolve(value)
      // }).catch(err => {
      //   reject(err)
      // })
      p.then(resolve, reject)
    }
  })
}
过气美图社 2022-05-04 13:55:51

Promise._race = function(Promises) {
return new Promise((resolve, reject) => {
Promises.forEach(p => p.then(resolve, reject))
})
}

蓝礼 2022-05-04 13:55:48
let p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('success')
    }, 100)
})
let p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject('failed')
    }, 500)
})

/**
 * 实现一个race
 * @param {Array} array 
 */
let race = function (array) {
    return new Promise((resolve, reject) => {
        let len = array.length;
        while (len--) {
            array[len].then(res => {
                return resolve(res);
            }).catch(err => {
                return reject(err);
            })
        }
    })
}
// 调用
race([p1, p2]).then(res => {
    console.log(res);
}).catch(err => {
    console.error(err);
})
像极了他 2022-05-04 13:54:56
 Promice.race= function(PromiseArr){
        let hasResolve = false
        return new PromiceA((resolve,reject)=>{
            PromiseArr.forEach(promiseItem=>{
                promiseItem.then(res=>{
                    !hasResolve && resolve(res)
                    hasResolve = true
                },(err)=>{
                   !hasResolve && reject(err)
                })
            })
        })
    }
囍笑 2022-05-04 13:54:13
const PromiseRace = (iterable)=>{
    return new Promise((resolve, reject) => {
      for (const p of iterable) {
        Promise.resolve(p).then(resolve).catch(reject)
      }
    })
  }
有深☉意 2022-05-04 13:53:37
Promise.miniRace = function(promises) {

    return new Promise((rs,rj)=>{
        try {
            // 检查输入值是否可迭代
            iteratorCheck(promises)

            const len = promises.length;
            let promiseStatusChanged = false;

            for (let i = 0; i < len; i++) {
                if (promiseStatusChanged)
                    break;
                // 使用 Promise.resolve 包装 thenable 和 非thenable 值
                Promise.resolve(promises[i]).then(rs).catch(rj).finally(()=>{
                    promiseStatusChanged = true
                }
                )
            }

        } catch (e) {
            rj(e)
        }

    }
    )
}

    function iteratorCheck(data) {
        if (!data[Symbol.iterator] || typeof data[Symbol.iterator] !== 'function') {
            const simpleType = typeof data;
            let errMsg = simpleType
            if (['number', 'boolean'].includes(simpleType) || data === null) {
                errMsg += ` ${String(data)}`
            }

            throw new TypeError(`${errMsg} is not iterable (cannot read property Symbol(Symbol.iterator))`)
        }
    }
泪之魂 2022-05-04 13:19:54

基本和上面的例子差不多,不同点是每个传入值使用Promise.resolve转为Promise对象,兼容非Promise对象

const _race = (p)=>{
	return new Promise((resolve, reject)=>{
		p.forEach((item)=>{
			Promise.resolve(item).then(resolve, reject)
		})
	})
}
不必你懂 2022-05-04 12:16:29
Promise.myrace = function(iterator) {
    return new Promise ((resolve,reject) => {
        try {
            let it = iterator[Symbol.iterator]();
            while(true) {
                let res = it.next();
                console.log(res);
                if(res.done) break;
                if(res.value instanceof Promise) {
                    res.value.then(resolve,reject);
                } else {
                    resolve(res.value)
                }
                
            }
        } catch (error) {
            reject(error)
        }
    }) 
}
等你爱我 2022-05-03 21:36:50
Promise._race = promises => new Promise((resolve, reject) => {
	promises.forEach(promise => {
		promise.then(resolve, reject)
	})
})
~没有更多了~

关于作者

無處可尋

暂无简介

文章
评论
28 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文