promise用法详情

1.含义

promise 是异步编程的一种解决方案  ,比传统的解决方案(回调函数和事件   ---> 更加的合理和强大)

  被ES6 写写进了语言的标准,统一了用法 ,原生提供了Promise对象。

2.特点:

对象状态不受外界影响  Promise对象代表一个异步操作,有三种状态: pending(进行中)  fufilled(已成功)  rejected(已失败)。

  只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

 3.用法:

  ES6 规定 Promise对象是一个构造函数,用来生成  Promise实例。

const promiseA = new Promise(function(resolve, reject) {
  // ... some code
  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject. 它们是两个函数。 由JavaScript引擎提供,

不用自己部署。调用PromiseA 函数时,必须要执行 resolve('成功参数') 或者 reject('失败参数)两者其中之一(可以不传参)!否则就一直时pending状态

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;

reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

1 promiseA.then(function(value) {
2   // success
3 }, function(error) {
4   // failure
5 });

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数

举例说明:

1 const p1 = new Promise(function (resolve, reject) {
2   // ...
3 });
4  
5 const p2 = new Promise(function (resolve, reject) {
6   // ...
7   resolve(p1);
})

解释:

这里,p1的状态决定了p2的状态。如果p1的状态是pending,那么p2的回调函数就会等待p1的状态改变;如果p1的状态已经是resolved或者rejected,那么p2的回调函数将会立刻执行。

4.Promise.prototype.then()

then方法是定义在原型对象  Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。前面说过,

then方法的第一个参数时 resolve状态的回调函数。第二个参数(可选)是rejected状态的回调函数。

 

采用链式的then,可以指定一组按照次序调用的回调函数。执行顺序的规则是:

首先,同步的操作依次按照顺序执行,其次再是执行异步操作,且异步操作按照耗时多少的顺序输出结果。

 1  var p=new Promise(function (resolve,reject) {
 2         console.log('start')
 3         setTimeout(function (){
 4             console.log(111)
 5             resolve();
 6         }, 1000)    
 7     })
 8     
 9     p.then(v=>{
10         console.log(222)
11         setTimeout(function () {
12             console.log(333)
13         }, 3000)
14     }).then(v=>{
15         console.log(444)
16     }).then(v=>{
17         setTimeout(function () {
18             console.log(555)
19         }, 2000)
20         console.log(666)
21     })
22 结果为:立即输出 start,1秒后输出111,再立即依次输出222,444,666,再过2秒输出555,再过1秒输出333
 1 再看一个复杂的例子:
 3     var p1=new Promise(function (resolve,reject) {
 4         console.log('start')
 5         setTimeout(function (){
 6             console.log("000")
 7             resolve();
 8         }, 1000)    
 9     })
10     var p2=new Promise(function (resolve,reject) {
11         console.log('start2')
12         setTimeout(function (){
13             console.log(111)
14             resolve(p1);
15         }, 1000)    
16     })
17     p2.then(v=>{
18         console.log(222)
19         setTimeout(function () {
20             console.log(333)
21         }, 4000)
22     }).then(v=>{
23         console.log(444)
24     }).then(v=>{
25         setTimeout(function () {
26             console.log(555)
27         }, 1000)
28         console.log(666)
29     })
30     p1.then(v=>{
31         console.log(777)
32         setTimeout(function () {
33             console.log(888)
34         }, 3000)
35     }).then(v=>{
36         console.log(999)
37     }).then(v=>{
38         setTimeout(function () {
39             console.log(101010)
40         }, 2000)
41         console.log(111111)
42     })
43 p1和p2都会立即执行,promise内部同步操作优先于异步操作,先输出start和start2,
  然后p2以p1的结果作为参数,所以会等待p1执行完(resolve或reject),
  再立即执行,即先等一秒立即输出 000,此时p1为resolve,
  立即执行then的同步操作,输出 777 999 111111,等待完成p1执行结束,
  再立即执行p2的同步操作,输出 111 222 444 666,此时同步操作全部执行完毕。
  接着执行异步操作,四个异步操作按耗时计算,依次输出555,101010,888,333

5. Promise.Prototype.catch()

Promise.prototype.catch方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。可以捕捉到promise内的错误和reject方法执行,以及它前面的then回调里面的错误。当promise内状态为reject时,它前面的then方法都不执行,直接执行catch方法,但是它之后的then方法不受影响秒回继续执行。

一般来说,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。

6.Promise.prototype.finally()

finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作,与then和catch同一级别的位置。该方法是 ES2018 引入标准的。

7.Promise.all()

 Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.all([p1, p2, p3]);

p的状态由p1p2p3决定,分成两种情况。

(1)只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。

p.then([r1,r2,r3]=>{
    console.log(r1,r2,r3)
}).catch(err=>{
    console.log(err)
})

(2)只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

 

posted @ 2020-12-18 23:22  诗亦0615  阅读(105)  评论(0编辑  收藏  举报