前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【译】Javascript 中的 Promise

【译】Javascript 中的 Promise

作者头像
腾讯IVWEB团队
发布2020-06-28 11:05:50
6880
发布2020-06-28 11:05:50
举报

原文地址:Promises In Javascriptundefined日期:2019-04-14

在 Javascript 中,Promise 是一种用作最初未知的数据特殊的对象。

这个概念并不是 Javascript 特有的,其他语言中也存在类似的结构。

它们在 Java、Python、Lisp、C++及其他不同语言中有不同的名字,例如featuresdeferredsdelays等等。

Promise一词由 Daniel P. Friedman 和 David Wise 在1976年名为《应用程序设计对多处理的影响》的论文中首次提出。

PromiseJavaScript用于处理异步操作的结果。

将 Callback 重构为 Promise

例如下面这段代码中,我们使用 callback 来执行异步操作。

代码语言:javascript
复制
setTimeout(() => {
  console.log("Async operation.");
}, 1000);

我们可以使Promise重构这段代码。

代码语言:javascript
复制
const promiseSetTimeout = ms => new Promise(resolve => setTimeout(resolve, ms));

promiseSetTimeout(1000).then(() => console.log("Async operation"));

这里我们使用Promise实例的then方法在Promise被解决后执行操作。

ES6 中也可以使用 async/await 语法来处理Promise

代码语言:javascript
复制
const promiseSetTimeout = ms => new Promise(resolve => setTimeout(resolve, ms));

await promiseSetTimeout(1000)
console.log("Async operation");
// 1000ms 后被执行

Promise 对象

Promise 存在三种不同的状态:

  • Pending - Promise 的初始状态
  • Resolved - 操作成功完成时的状态
  • Rejected - 操作执行失败时的状态

Promise的状态只能改变一次,即从PendingResolved/Rejected,并且不能再次改变为Pending

Promise实例化接受一个函数为参数,如下例中executor,在实例化Promise之后会立即执行executor函数。

代码语言:javascript
复制
const promise = new Promise(executor);

executor 函数接受两个参数,分别为 resolvereject

代码语言:javascript
复制
const promise = new Promise((resolve, reject) => {
  resolve("Async success!");
});

调用resolve后会将Promise的状态转换为 resolved。在调用成功后,可以通过Promise实例中的then方法来获取执行的结果。

代码语言:javascript
复制
promise.then(result => console.log(result));

当然也可以在executor中调用reject

代码语言:javascript
复制
const promise = new Promise((resolve, reject) => {
  reject("Async failed!");
});

这样的话,Promise的状态将会变为rejectedPromise中也提供了catch方法来处理这种状态。

译者注:如果没有通过注册过rejectedcallback,会导致Promise内部抛出一个未捕获的错误。

代码语言:javascript
复制
promise.catch(result => console.log(result));

Promise实例中也提供了finally方法,不论Promise的状态转换为resolved还是rejected都会执行该方法。

代码语言:javascript
复制
promise.finally(result => console.log(result));

译者注:then方法可以同时接收两个参数,finally更像是then方法的语法糖。

Promise 的链式调用

thencatch都会返回一个Promise实例,所以我们可以得到一种链式的写法。

代码语言:javascript
复制
new Promise((resolve, reject) => {
  setTimeout(() => resolve(1), 1000);
})
  .then(result => {
    console.log(result); // 1
    return result + 1;
  })
  .then(result => {
    console.log(result); // 2
    return result + 1;
  })
  .then(result => {
    console.log(result); // 3
    return result + 1;
  });

在上面的例子中,每次调用then方法都会返回一个新的Promise,我们可以在then方法之后再次调用其返回的Promisethen方法,所以,后面的callback只能在上一个Promise变为resolved之后被依次执行。

同样的,我们可以使用then为同一个 Promise 增加多个回调,但是这样我们就不能链式调用了。

代码语言:javascript
复制
const promise = new Promise((resolve, reject) => {
  setTimeout(() => resolve(1), 1000);
});

promise.then(result => {
  console.log(result); // 1
  return result + 1;
});

promise.then(result => {
  console.log(result); // 1
  return result + 1;
});

promise.then(result => {
  console.log(result); // 1
  return result + 1;
});

在上面的例子中,同一个原始Promisethen方法的执行相互独立。

译者注:这里相互独立指的是一个then的执行结果并不会改变该Promise的执行结果,同样也不会影响到其他then方法的执行。

Promise 静态方法

Promise对象上也提供了静态方法。

Promise.resolve

当我们需要将已知值作为Promise返回时使用,该方法返回一个给定值且状态为resolvedPromise

代码语言:javascript
复制
const resolvedPromise = Promise.resolve("Success");

Promise.reject

该方法返回一个错误且状态为rejectedPromise

代码语言:javascript
复制
const rejectedPromise = Promise.reject("Failure");

Promise.all

该方法接受一个可迭代的Promise容器(通常是一个数组)并返回一个新的Promise,当容器中所有Promise的状态变为resolved时该方法返回的Promise的状态才变为resolved,并且将所有Promise的结果通过then方法返回。

代码语言:javascript
复制
const allPromises = Promise.all([promise1, promise2, promise3]);

then方法中接收到的结果与容器中的Promise顺序一致。

代码语言:javascript
复制
Promise.all([
  new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
  new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
  new Promise(resolve => setTimeout(() => resolve(3), 1000)) // 3
]).then(console.log); // [1,2,3]

上例中,即使第一个Promise的状态最后转换为resolved,其结果仍将是值数组中的第一个。

译者注:容器中只要有一个Promise的状态为rejected,都会导致该方法返回的Promiserejected

Promise.race

该方法接受一个可迭代的Promise容器(通常是一个数组)并返回一个新的Promise,当容器中存在一个Promise的状态变为resolved/rejected时该方法返回的Promise的状态就变为resolved/rejected,并且将该Promise的结果/错误通过then/catch方法返回。

代码语言:javascript
复制
Promise.race([
  new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
  new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
  new Promise(resolve => setTimeout(() => reject(3), 1000)) // 3
]).then(console.log); // 3
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 将 Callback 重构为 Promise
  • Promise 对象
  • Promise 的链式调用
  • Promise 静态方法
    • Promise.resolve
      • Promise.reject
        • Promise.all
          • Promise.race
          相关产品与服务
          容器服务
          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档