初步了解Promise

极客破浪者
• 阅读 1078

问题来了

Promise 有几种状态?
Promise 有什么优缺点?
Promise构造函数是同步还是异步执行,then呢?
Promise和setTimeout的区别?
如何实现 Promise.all?
如何实现 Promise.finally?

Promise知识点

1. Promise

1)定义
保存着某个未来才会结束的事件(异步操作)的容器

2)特点
(1)对象的状态不受外界影响。三个状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)。只有异步操作的结果,可以决定当前状态。
(2)状态只能改变一次,任何时候都能得到该结果。两种状态改变的情况:pending->fulfilled、pending->rejected。状态一直保持,给Promise对象添加回调函数,能得到该结果。

3)优缺点
(1)可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数;Promise对象提供统一的接口,是的控制异常操作更加容易。
(2)无法取消Promise,一旦新建立即执行;若不设置回调函数,则Promise内部抛出的异常反应不到外部;pending状态无法得知进展。

2. Promise.prototype.then()

1)定义
为Promise实例添加状态改变时的回调函数。.then(resolved的回调函数,rejected的回调函数[可选])

tips:
then方法返回的是一个新的Promise实例(不是原来的那个Promise实例),因此可以链式,如:.then().then()。
采用链式的then,可以指定一组按照次序执行的回调函数。

3. Promise.prototype.catch()

1)定义
then(null, rehection)或.then(undefiend, rejection)的别名,用于指定发生错误时的回调函数。

tips:
promise对象的错误具有“冒泡”性质,错误一直向后传递,直至被捕获。
promise对象错误不会传递到外层代码,即不同于try/catch,(报错后不会终止外层代码执行)。

4. Promise.prototype.finally()

1)定义
不论Promise对象最终状态如何,都会执行的操作(ES2018)。本质上是then方法的特例。
2)特点
不接受任何参数,不影响原Promise的状态。
3)实际应用
post请求loading,在请求结束后不论结果如何都关闭loading

5. Promise.all()

作用:
将多个Promise实例,包装成一个Promise实例。

特点:
新Promise对象(p)的状态由Promise实例数组([p1, p2, p3])决定。
当p1、 p2、 p3状态都为fulfilled,p的状态为fulfilled,p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
当p1、 p2、 p3中有一个状态为rejected,p的状态为rejected,第一个被reject的实例的返回值,会传递给p的回调函数。

问题解答

1. Promise有几种状态

pending(进行中)、fulfilled(已成功)和rejected(已失败)

2. Promise有什么优缺点

可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数;Promise对象提供统一的接口,是的控制异常操作更加容易。
无法取消Promise,一旦新建立即执行;若不设置回调函数,则Promise内部抛出的异常反应不到外部;pending状态无法得知进展。

3. Promise构造函数是同步还是异步执行,then呢?

构造函数同步执行,then异步执行

4. Promise和setTimeout的区别

setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.then()在本轮“事件循环”结束时执行。

5.如何实现 Promise.all

function promiseAll(promises) {
  return new Promise((resolve, reject) => {
    let resultCount = 0;
    let results = new Array(promises.length);

    for (let i = 0; i < promises.length; i++) {
      promises[i].then(value => {
                resultCount++;
        results[i] = value;
        if (resultCount === promises.length) {
          return resolve(results)
        }
      }, error => {
        reject(error)
      })
    }
  })
}

let p1 = new Promise(resolve => resolve('p1'))
let p2 = new Promise(resolve => resolve('p2'))
let p3 = Promise.reject('p3 error')

Promise.all([p1, p2, p3]).then(results => {
  console.log(results)
}).catch(error => {
  console.log(error)      // 'p3 error'
})

promiseAll([p1, p2]).then(results => {
  console.log(results)    // ['p1', 'p2']
}).catch(error => {
  console.log(error)
})

6.如何实现 Promise.finally

Promise.prototype.finally = function (callback) {
  let P = this.constructor; // 构造函数
  console.log(P);
  return this.then(
    value  => P.resolve(callback()).then(() => value),  // resolve
    reason => P.resolve(callback()).then(() => { throw reason })  // reject
  );
};

参考文章

《ECMAScript 6 入门——阮一峰》

点赞
收藏
评论区
推荐文章
Chase620 Chase620
4年前
Promise从入门到拿Offer之手写Promise
1、Promise构造函数的实现Promise构造函数用来声明示例对象,需要传入一个执行器函数。其中包括resolve函数和reject函数,以及几个重要的属性:状态属性、结果属性和回调函数队列。构造函数的基本框架resolve函数用于异步处理成功后调用的函数。其中包括验证对象状态修改次数,修改promise实例对象状态,异步调用成功的回调函数
Stella981 Stella981
3年前
Promise和Observable的映射
前言1.promise解决了嵌套地狱的问题,Observable解决了promise只有一个结果,和不可以取消的问题。2.使用的是rxjs6版本。3.这篇文章是方便使用Observable的API替换Promise的API。正常用法promise.then(result{}).ca
Stella981 Stella981
3年前
JavaScript中Promise 使用、原理以及实现过程
1.什么是Promisepromise是目前JS异步编程的主流解决方案,遵循Promises/A方案。2.Promise原理简析(1)promise本身相当于一个状态机,拥有三种状态pendingfulfilledrejected一个promise对象初始化时
Stella981 Stella981
3年前
ES6 Promise 让异步函数顺序执行
应用ES6的内置对象Promise,让异步函数按顺序执行的例子如下:!(https://oscimg.oschina.net/oscnet/9d7da385127c5df3cdf50b984cc4bca58c7.jpg)上边是四个用Promise处理过的异步执行的函数:fn1、fn2、fn3、fn4下面,让其按顺序执行
Stella981 Stella981
3年前
Promise的奇怪用法和自己实现一个Promise
原文链接: Promise的奇怪用法和自己实现一个Promise(https://my.oschina.net/ahaoboy/blog/4645165)使用Promise实现一个页面所有图片加载完毕的回调importReact,{useEffect}from"react";exportdefault()
Stella981 Stella981
3年前
Javascript 中的神器——Promise
_摘要:_ 回调函数真正的问题在于他剥夺了我们使用return和throw这些关键字的能力。而Promise很好地解决了这一切回调函数真正的问题在于他剥夺了我们使用return和throw这些关键字的能力。而Promise很好地解决了这一切Promise概念所谓Promise,就是ES6原生提供的一个
Stella981 Stella981
3年前
JS微任务 宏任务,Promise、setTimeout、setImmediate运行顺序实测
结论如下1.虽然理论上应当先运行Promise,再运行setTimeout。但是由于历史版本或使用polyfill,使得Promise未必优先运行。2.setImmediate未必比setTimeout早运行3.在最新浏览器中Promise会早于事件冒泡运行,在设计框架时应考虑这一情况以下是实测情况\
Stella981 Stella981
3年前
Promise进一步阅读
下面是几篇比较好的Promise文章:\1\Promise是怎么工作的,http://wengeezhang.com/?p13(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwengeezhang.com%2F%3Fp%3D13)\2\JavaScript进阶之路
Stella981 Stella981
3年前
Promise 多重链式调用
Promise对象是用于异步操作的。Promise的真正强大之处在于它的多重链式调用,可以避免层层嵌套回调。如果我们在第一次ajax请求后,还要用它返回的结果再次请求呢?使用Promise,我们就可以利用then进行「链式回调」,将异步操作以同步操作的流程表示出来。以下是个小Demo:/e.g/sen
Promise规范与原理解析 | 京东物流技术团队
Promise对象用于清晰的处理异步任务的完成,返回最终的结果值,本次分享主要介绍Promise的基本属性以及Promise内部的基础实现,能够帮我们更明确使用场景、更快速定位问题。
京东云开发者 京东云开发者
7个月前
Promise规范与原理解析
作者:京东物流孙琦摘要Promise对象用于清晰的处理异步任务的完成,返回最终的结果值,本次分享主要介绍Promise的基本属性以及Promise内部的基础实现,能够帮我们更明确使用场景、更快速定位问题。Promise出现的原因首先我们先来看一段代码:异步