语法
Promise.race(iterable);
参数:
iterable
可迭代对象,类似Array。
返回值:
一个待定的 Promise 只要给定的迭代中的一个promise解决或拒绝,就采用第一个promise的值作为它的值,从而异步地解析或拒绝(一旦堆栈为空)。
理解
Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
理解1:
var p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "one");
});
var p2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "two");
});
Promise.race([p1, p2]).then((value) => {
console.log(value);
// Both resolve, but p2 is faster
});
// expected output: "two"
理解2:
var p3 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, "three");
});
var p4 = new Promise(function(resolve, reject) {
setTimeout(reject, 500, "four");
});
Promise.race([p3, p4]).then(function(value) {
console.log(value); // "three"
// p3 更快,所以它完成了
}, function(reason) {
// 未被调用
});
理解3:
var p5 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, "five");
});
var p6 = new Promise(function(resolve, reject) {
setTimeout(reject, 100, "six");
});
Promise.race([p5, p6]).then(function(value) {
// 未被调用
}, function(reason) {
console.log(reason); // "six"
// p6 更快,所以它失败了
});
理解4:
// we are passing as argument an array of promises that are already resolved,
// to trigger Promise.race as soon as possible
var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)];
var p = Promise.race(resolvedPromisesArray);
// immediately logging the value of p
console.log(p);
// using setTimeout we can execute code after the stack is empty
setTimeout(function(){
console.log('the stack is now empty');
console.log(p);
});
// logs, in order:
// Promise { <state>: "pending" }
// the stack is now empty
// Promise { <state>: "fulfilled", <value>: 33 }
Promise.race 的特点:
- Promise.race返回的仍然是一个Promise. 它的状态与第一个完成的Promise的状态相同。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个Promise是哪一种状态。
- 如果传入的参数是不可迭代的,那么将会抛出错误。
- 如果传的参数数组是空,那么返回的 promise 将永远等待。
- 如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺,则 Promise.race 将解析为迭代中找到的第一个值。
实现
Promise._race = function (promises) {
return new Promise((resolve, reject) => {
if (typeof promises[Symbol.iterator] !== "function") {
Promise.reject("args is not iteratable!");
}
if (promises.length === 0) {
return;
} else {
for (let i = 0; i < promises.length; i++) {
Promise.resolve(
promises[i].then(
(data) => {
resolve(data);
return;
},
(err) => {
reject(err);
return;
}
)
);
}
}
});
};
More
Promise.race()
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/race
“你能手写一个 Promise 吗”
https://zhuanlan.zhihu.com/p/183801144
如何实现 Promise.race
https://github.com/YvetteLau/Blog/issues/13