zl程序教程

您现在的位置是:首页 >  Java

当前栏目

promise.all和promise.race

2023-02-18 16:29:05 时间

bug收集:专门解决与收集bug的网站

网址:www.bugshouji.com

今天为大家分享下:Promise 中的 all 与 race 两个方法

01

promise.all 方法

Promise.all可以将多个实例组装成一个新的实例,成功的时候返回一个成功数组,失败的时候则返回最先被reject失败状态的值

比如:当一个页面需要在很多个模块的数据都返回回来时才正常显示,否则loading

let wake = (time)=>{
return new Promise((resolve,reject) =>{setTimeout(()=>{
     resolve(`${itime / 1000}秒后醒来`)
     }, time)
})
}
let p1 = wake(3000)
let p2 = wake( 2000)
Promise.all([p1,p2]).then((result)=>{
console.log(result);  //['3秒后醒来','2秒后醒来']
}).catch((error)=>{
console.log(error)
})

当数组里的P1,P2都执行完成时,页面才显示。

值得注意的是,返回的数组结果顺序不会改变,即使P2的返回要比P1的返回快,顺序依然是P1,P2

示例1:

如果参数中包含非 promise 值,这些值将被忽略,但仍然会被在返回数组中(如果 promise 完成的话)

var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([p1, p2, p3]).then(values => {
  console.log(values); // [3, 1337, "foo"]
});

示例2:Promise.all 的异步和同步

Promise.all 当且仅当传入的可迭代对象为空时为同步,

var p = Promise.all([]); // will be immediately resolved
var p2 = Promise.all([1337, "hi"]); // non-promise values will be ignored, but the evaluation will be done asynchronously
console.log(p);
console.log(p2)
setTimeout(function(){
    console.log('the stack is now empty');
    console.log(p2);
});

// logs
// Promise { <state>: "fulfilled", <value>: Array[0] }
// Promise { <state>: "pending" }
// the stack is now empty
// Promise { <state>: "fulfilled", <value>: Array[2] }

如果 Promise.all 失败,也是一样的

var mixedPromisesArray = [Promise.resolve(33), Promise.reject(44)];
var p = Promise.all(mixedPromisesArray);
console.log(p);
setTimeout(function(){
    console.log('the stack is now empty');
    console.log(p);
});

// logs
// Promise { <state>: "pending" }
// the stack is now empty
// Promise { <state>: "rejected", <reason>: 44 }

示例3:Promise.all 的快速返回失败行为

Promise.all 在任意一个传入的 promise 失败时返回失败。

例如,如果你传入的 promise中,有四个 promise 在一定的时间之后调用成功函数,有一个立即调用失败函数,那么 Promise.all 将立即变为失败。

var p1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, 'one');
});
var p2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 2000, 'two');
});
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 3000, 'three');
});
var p4 = new Promise((resolve, reject) => {
  setTimeout(resolve, 4000, 'four');
});
var p5 = new Promise((resolve, reject) => {
  reject('reject');
});

Promise.all([p1, p2, p3, p4, p5]).then(values => {
  console.log(values);
}, reason => {
  console.log(reason)
});

//From console:
//"reject"

//You can also use .catch
Promise.all([p1, p2, p3, p4, p5]).then(values => {
  console.log(values);
}).catch(reason => {
  console.log(reason)
});

//From console:
//"reject"

02

promise.race 方法

race是赛跑的意思,也就是说Promise.race([p1, p2, p3])里面的结果哪个获取的快,就返回哪个结果,不管结果本身是成功还是失败

var p1 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 500, "one");
});
var p2 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 100, "two");
});

Promise.race([p1, p2]).then(function(value) {
  console.log(value); // "two"
  // 两个都完成,但 p2 更快
});

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) {
  // 未被调用
});

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 更快,所以它失败了
});

示例1:Promise.race 的异步性

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);
});

// 输出结果: 
// Promise { <state>: "pending" }
// the stack is now empty
// Promise { <state>: "fulfilled", <value>: 33 }

03

相关面试题

promise.then子句里return一个null,会走到下一个then吗。

答案:会

promise.catch子句可以捕获错误,那么catch里的错误可以捕获吗。

答案:不会


苟有恒 , 何必三更眠五更起