new Promise用法

promise要解决的问题

回调函数问题
问题一:回调函数多层嵌套调用(回调地狱)
问题二:每次回调的结果存在成功或失败的可能性

使用 promise 解决
解决问题一:promise 通过 .then 实现链式调用
解决问题二:promise 通过 .catch 统一捕获异常

Promise 的 3 种状态。

•	fulfilled:表示操作已经成功完成,并准备返回结果。
•	rejected:表示操作执行失败,代码可能有异常或人为地调用了 reject()。
•	pending:如果状态既不是 fulfilled 也不是 rejected,则为 pending 状态,表示操作执行中。

使用 new 创建 Promise 对象之后,执行器中的代码会立即执行,此时 Promise 为 pending 状态;当调用 resolve() 函数之后,会把 Promise 的 pending 状态改为 fulfilled 状态;类似地,reject() 函数会把它从 pending 改为 rejected 状态。

fulfilled 和 rejected 状态统称为settled,可以认为是完成状态(无论是成功还是失败)。

基本语法如下:

const promise = new Promise((resolve, reject) => {
// asynchronous code goes here
});

我们首先使用Promise构造函数实例化一个新的 promise 对象,并向它传递一个回调函数。回调有两个参数,resolve和reject,它们都是函数。我们所有的异步代码都在该回调中。

如果一切运行成功,承诺将通过调用来实现resolve。如果出现错误,则会调用reject。我们可以将值传递给这两种方法,这些方法将在使用代码中可用。

Promise 提供了4种方式执行多个 Promise,分别是:
Promise.all()
Promise.allSettled()
Promise.any()
Promise.race()
接下来分别看一下它们的作用和区别。

1、Promise.all()
Promise.all() 静态方法接受一个 Promise 可迭代对象作为输入,并返回一个 Promise。当所有输入的 Promise 都被兑现时,返回的 Promise 也将被兑现(即使传入的是一个空的可迭代对象),并返回一个包含所有兑现值的数组。如果输入的任何 Promise 被拒绝,则返回的 Promise 将被拒绝,并带有第一个被拒绝的原因

Promise.all 等待所有兑现(或第一个拒绝)的结果。

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

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

2、Promise.allSettled()
方法是 promise 并发方法之一。在你有多个不依赖于彼此成功完成的异步任务时,或者你总是想知道每个 promise 的结果时,使用 Promise.allSettled() 。

相比之下,如果任务相互依赖,或者如果你想在任何 promise 被拒绝时立即拒绝,Promise.all() 返回的 Promise 可能更合适。

Promise.allSettled([
  Promise.resolve(33),
  new Promise((resolve) => setTimeout(() => resolve(66), 0)),
  99,
  Promise.reject(new Error("一个错误")),
]).then((values) => console.log(values));

// [
//   { status: 'fulfilled', value: 33 },
//   { status: 'fulfilled', value: 66 },
//   { status: 'fulfilled', value: 99 },
//   { status: 'rejected', reason: Error: 一个错误 }
// ]

3、Promise.any()
当输入的任何一个 Promise 兑现时,这个返回的 Promise 将会兑现,并返回第一个兑现的值。当所有输入 Promise 都被拒绝(包括传递了空的可迭代对象)时,它会以一个包含拒绝原因数组的 AggregateError 拒绝。

该方法对于返回第一个兑现的 Promise 非常有用。一旦有一个 Promise 兑现,它就会立即返回,因此不会等待其他 Promise 完成

与 Promise.all() 返回一个兑现值数组不同的是,我们只会得到一个兑现值(假设至少有一个 Promise 被兑现)。此方法对于那些如果我们只需要一个 Promise 被兑现,但不在意哪一个被兑现的情况更有益。请注意另一个区别:该方法在接收到空的可迭代对象时会拒绝,因为实际上,该可迭代对象不包含任何兑现的项。你可以将 Promise.any() 和 Promise.all() 与 Array.prototype.some() 和 Array.prototype.every() 进行比较。

同时,与 Promise.race() 返回第一个敲定(无论是兑现还是拒绝)的值不同的是,该方法返回第一个兑现的值。该方法忽略所有被拒绝的 Promise,直到第一个被兑现的 Promise。

const pErr = new Promise((resolve, reject) => {
  reject("总是失败");
});

const pSlow = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, "最终完成");
});

const pFast = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, "很快完成");
});

Promise.any([pErr, pSlow, pFast]).then((value) => {
  console.log(value);
  // pFast 第一个兑现
});
// 打印:
// 很快完成

4、Promise.race()
这个返回的 promise 会随着第一个 promise 的敲定而敲定。

当你想要第一个异步任务完成时,但不关心它的最终状态(即它既可以成功也可以失败)时,它就非常有用。

如果可迭代对象中包含一个或多个非 promise 值和/或已敲定的 promise,则 Promise.race() 将以可迭代对象中找到的第一个此类值敲定。

function sleep(time, value, state) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (state === "兑现") {
        return resolve(value);
      } else {
        return reject(new Error(value));
      }
    }, time);
  });
}

const p1 = sleep(500, "一", "兑现");
const p2 = sleep(100, "二", "兑现");

Promise.race([p1, p2]).then((value) => {
  console.log(value); // “二”
});

const p3 = sleep(100, "三", "兑现");
const p4 = sleep(500, "四", "拒绝");

Promise.race([p3, p4]).then(
  (value) => {
    console.log(value); // “三”
    // p3 更快,所以它兑现
  },
  (error) => {
    // 不会被调用
  },
);

const p5 = sleep(500, "五", "兑现");
const p6 = sleep(100, "六", "拒绝");

Promise.race([p5, p6]).then(
  (value) => {
    // 不会被调用
  },
  (error) => {
    console.error(error.message); // “六”
    // p6 更快,所以它拒绝
  },
);

相关推荐

  1. new Promise

    2023-12-05 22:54:02       27 阅读
  2. qt 定时器

    2023-12-05 22:54:02       42 阅读
  3. fmt

    2023-12-05 22:54:02       37 阅读
  4. not exists

    2023-12-05 22:54:02       41 阅读
  5. 详解WebMvcConfigurer

    2023-12-05 22:54:02       27 阅读
  6. Tinyxml基本

    2023-12-05 22:54:02       39 阅读
  7. man

    2023-12-05 22:54:02       33 阅读
  8. mybatisPlus 常见

    2023-12-05 22:54:02       31 阅读
  9. v-show

    2023-12-05 22:54:02       41 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-05 22:54:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-05 22:54:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-05 22:54:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-05 22:54:02       18 阅读

热门阅读

  1. 【数据库连接池】01:连接池初始化

    2023-12-05 22:54:02       36 阅读
  2. Go查询Elasticsearch

    2023-12-05 22:54:02       39 阅读
  3. Python 3 使用 write()、writelines() 函数写入文件

    2023-12-05 22:54:02       32 阅读
  4. ClickHouse:真正的OLAP列式DBMS

    2023-12-05 22:54:02       42 阅读
  5. npm私仓 verdaccio搭建 & 发布到私仓 使用

    2023-12-05 22:54:02       29 阅读
  6. ElasticSearch之Force merge API

    2023-12-05 22:54:02       41 阅读
  7. Git多库多账号本地SSH连接配置方法

    2023-12-05 22:54:02       46 阅读
  8. npm run build打包jquery项目

    2023-12-05 22:54:02       34 阅读
  9. macOS/Ubuntu - ftp 工具

    2023-12-05 22:54:02       128 阅读
  10. Python与ArcGIS系列(十三)UpdateCursor方法

    2023-12-05 22:54:02       38 阅读
  11. Python与ArcGIS系列(十二)InsertCursor方法

    2023-12-05 22:54:02       33 阅读
  12. golang 集成logrus日志框架

    2023-12-05 22:54:02       38 阅读
  13. tcexam 本地容器化搭建

    2023-12-05 22:54:02       43 阅读
  14. ClickHouse入门手册1.0

    2023-12-05 22:54:02       32 阅读