Promise总结

Promise.then() 的返回值仍然是 Promise 对象

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    let p = new Promise((resoleve, reject) => {
      setTimeout(() => {
        resoleve("返回值");
      }, 1000);
    });

    const backP = p.then((res) => {
      console.log("----打印:", res);
    //   return "你好"
      return Promise.resolve(res + "成功的promise");
    });
    const finallyBackP = backP.then((res) => {
      console.log("----打印:", res);
      return Promise.reject("最后是失败的promise");
    });
    setTimeout(() => {
      console.log("----打印:backP", backP);
    }, 2000);
    setTimeout(() => {
      console.log("----打印:finallyBackPP", finallyBackP);
    }, 3000);

    //执行结果
    // ----打印: 返回值
    // ----打印: 返回值成功的promise
    // ----打印:backP Promise {<fulfilled>: '返回值成功的promise'}
    // ----打印:finallyBackPP Promise {<rejected>: '最后是失败的promise'}
  </script>
</html>

Promise.all 方法
Promise.all 是 JavaScript 中 Promise 对象的一个静态方法,它接受一个可迭代对象(通常是数组)作为参数,这个可迭代对象的每个成员都是一个 PromisePromise.all 会等待所有的 Promise 都成功解决(fulfilled)后,才完成(fulfill)它自身返回的 Promise,并且会返回一个包含所有 Promise 结果的数组。如果任何一个 Promise 被拒绝(rejected),Promise.all 将立即拒绝,并返回第一个被拒绝的 Promise 的结果。

下面是 Promise.all 的一些关键特性和用法:

基本用法

let promise1 = Promise.resolve(3);
let promise2 = Promise.resolve(4);
let promise3 = 42; // 非Promise对象会被立即视为已解决的Promise

Promise.all([promise1, promise2, promise3]).then(values => {
  console.log(values); // 输出: [3, 4, 42]
});

在这个例子中,Promise.all 接受一个包含三个 Promise 的数组。所有 Promise 都成功解决后,Promise.all 返回的 Promise 也会解决,并返回包含所有结果的数组。

错误处理

let promise1 = Promise.reject('error1');
let promise2 = Promise.resolve(4);

Promise.all([promise1, promise2]).catch(error => {
  console.log(error); // 输出: 'error1'
});

如果 promise1 被拒绝,Promise.all 将立即拒绝,并跳过其他 Promise 的结果,即使 promise2 成功解决。

Promise.allSettled 的区别

Promise.allSettled 是另一个静态方法,它不管 Promise 的结果如何,都会等待所有 Promise 结束(无论是解决还是拒绝),然后返回一个对象数组,每个对象包含对应的 Promise 结果。

应用场景

Promise.all 常用于需要并行处理多个异步操作,并且只有当所有操作都完成后才能继续执行的场景。例如,同时从多个源加载数据,只有所有数据都加载完成后,才能进行下一步处理。

注意事项

  • Promise.all 会立即执行,即使传入的数组为空。
  • 如果传入的可迭代对象中包含非 Promise 对象,它们会被立即视为已解决的 Promise,其结果就是它们自身。
  • 如果 Promise.all 的参数不是一个可迭代对象,将会抛出一个错误。

Promise.all 是并发处理异步操作的强大工具,正确使用它可以显著提高程序的效率和响应性。

var p1 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    resoleve("p1--3000");
  }, 3000);
});
var p2 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    resoleve("p2--1000");
  }, 1000);
});
var p3 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    console.log("----打印:看看是先执行失败,还是全部执行完再catch");
    resoleve("p3--5000");
  }, 5000);
});
 
//第一情况
 var promiseArr = [p1, p2, p3];
 console.time("promiseArr");
  Promise.all(promiseArr)
    .then((res) => {
      console.log("res", res); //res [ 'p1--3000', 'p2--1000', 'p3--5000' ]
      console.timeEnd("promiseArr"); // promiseArr: 5.020s
    })
    .catch((err) => console.log(err));
 
//另外情况
var p4 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    reject("p4--2000");
  }, 2000);
});
 
var promiseArr = [p1, p2, p3, p4];
console.time("promiseArr");
Promise.all(promiseArr)
  .then((res) => {
    console.log("res", res);
    console.timeEnd("promiseArr");
  })
  .catch((err) => console.log(err)); 
 
//打印顺序
//p4--2000
//输出----打印:看看是先执行失败,还是全部执行完再catch 
 
//解释:p3的输出,比上边catch晚输出因此,如果有失败状态,就会提前结束、去执行all里面的回调函数

Promise.any
截至目前(2023年),Promise.any 是一个相对较新的 JavaScript 特性,它并不是 ECMAScript 标准的一部分,而是在一些现代浏览器和 Node.js 版本中作为实验性特性提供。这个方法与 Promise.race 类似,但是它的行为是等待第一个解决的 Promise 而不是第一个拒绝的。

基本用法

Promise.any 接受一个可迭代对象(通常是数组),其中的每个成员都是一个 Promise 对象。如果数组中至少有一个 Promise 成功解决,Promise.any 返回的 Promise 将解决,并返回第一个解决的 Promise 的结果。如果所有传入的 Promise 都被拒绝,Promise.any 返回的 Promise 也会被拒绝,并返回一个包含所有拒绝原因的聚合错误。

let promise1 = new Promise((resolve, reject) => setTimeout(reject, 100, 'error1'));
let promise2 = new Promise((resolve, reject) => setTimeout(resolve, 50, 'success'));

Promise.any([promise1, promise2]).then(value => {
  console.log(value); // 输出: 'success'
}).catch(error => {
  console.error(error);
});

在这个例子中,promise2 是第一个解决的 Promise,所以 Promise.any 返回的 Promise 将解决并返回 'success'

错误处理

如果所有传入的 Promise 都被拒绝,Promise.any 返回的 Promise 将被拒绝,并返回一个 AggregateError 对象,它是 Error 的一个子类,包含所有拒绝的原因。

let promise1 = Promise.reject('error1');
let promise2 = Promise.reject('error2');

Promise.any([promise1, promise2]).catch(error => {
  console.log(error); // AggregateError
  console.log(error.errors); // ['error1', 'error2']
});

应用场景

Promise.any 适用于以下场景:

  • 当你想要快速尝试多个异步操作,只关心第一个成功的结果。
  • 当你想要实现超时逻辑,例如,尝试多个服务直到一个服务成功响应,或者在超时前等待第一个响应。

注意事项

  • Promise.any 并不广泛支持,使用前需要检查环境是否支持。
  • 如果传入的可迭代对象为空,Promise.any 返回的 Promise 将立即被拒绝,并返回一个 AggregateError,其 errors 属性为空数组。
  • 如果传入的可迭代对象中包含非 Promise 对象,它们会被立即视为已解决的 Promise,其结果就是它们自身。
    Promise.any 提供了一种新的方式来处理多个异步操作,允许开发者更快地响应第一个成功的结果,同时优雅地处理所有操作失败的情况。
    code
var p1 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    resoleve("p1--3000");
  }, 3000);
});
var p2 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    reject("p2--1000");
  }, 1000);
});
var p3 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    console.log("----打印p3");
    resoleve("p3--5000");
  }, 5000);
});
 
var promiseArr = [p1, p2, p3];
console.time("promiseArr");
Promise.any(promiseArr)
  .then((res) => {
    console.log("res", res); //res [ 'p1--3000', 'p2--1000', 'p3--5000' ]
    console.timeEnd("promiseArr"); // promiseArr: 5.020s
  })
  .catch((err) => console.log(err));
 
//输出顺序 --虽然p2已经执行完,但是为rejected状态,而any会返回第一个resolve状态的对象
//   res p1--3000
// promiseArr: 3.009s
// ----打印p3
 
//另外一种情况
var p1 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    reject("p1--3000");
  }, 3000);
});
var p2 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    reject("p2--1000");
  }, 1000);
});
var p3 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    console.log("----打印p3");
    reject("p3--5000");
  }, 5000);
});
 
var promiseArr = [p1, p2, p3];
console.time("promiseArr");
Promise.any(promiseArr)
  .then((res) => {
    console.log("res", res); //res [ 'p1--3000', 'p2--1000', 'p3--5000' ]
    console.timeEnd("promiseArr"); // promiseArr: 5.020s
  })
  .catch((err) => console.log(err));
 
//输出结果   解释--因为p1,2,3都是错误,所以any一直在等有成功的状态,所以知道p3结束后,没有成功的,就走catch那边
// ----打印p3
// [AggregateError: All promises were rejected] {
//   [errors]: [ 'p1--3000', 'p2--1000', 'p3--5000' ]
// }

Promise.race
方法接收的参数和.all、.any接收的参数一样,接收一个可迭代promise对象的数组,当任何一个promise的状态先确定(拒绝或者成功),则会执行.race中的回调函数,具体根据promise的状态 —和allSettled效果互斥

var p1 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    console.log("----打印:p1");
    resoleve("p1--3000");
  }, 3000);
});
 
let p2 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    reject("p2--1000");
  }, 1000);
});
 
Promise.race([p1, p2])
  .then((res) => {
    console.log("----打印:res", res);
  })
  .catch((err) => {
    console.log("----打印:err", err);
  });
 
//执行结果
//----打印:err p2--1000
//----打印:p1
 
//另外情况
 
let p3 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    resoleve("p3--500");
  }, 500);
});
 
Promise.race([p1, p2, p3])
  .then((res) => {
    console.log("----打印:res", res);
  })
  .catch((err) => {
    console.log("----打印:err", err);
  });
 
//打印结果
// ----打印:res p3--500
// ----打印:p1

Promise.allSettled

var p1 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    console.log("----打印:p1");
    resoleve("p1--3000");
  }, 3000);
});
 
let p2 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    reject("p2--1000");
  }, 1000);
});
 
let p3 = new Promise((resoleve, reject) => {
  setTimeout(() => {
    resoleve("p3--500");
  }, 500);
});
 
let p4 = new Promise((resolve, reject) => {
  throw new Error("抛出错误");
});
 
Promise.allSettled([p1, p2, p3, p4])
  .then((result) => {
    console.log("----打印:result", result);
  })
  .catch((err) => {
    console.log("----打印:", err); //不执行
  });
 
//执行结果
// ----打印:p1
// ----打印:result [
//   { status: 'fulfilled', value: 'p1--3000' },
//   { status: 'rejected', reason: 'p2--1000' },
//   { status: 'fulfilled', value: 'p3--500' },
//   {
//     status: 'rejected',
//     reason: Error: 抛出错误
//   }
// ]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值