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
方法。
finally
方法用于指定不管 Promise 对象最后状态如何,都会执行的操作,与then和catch同一级别的位置。该方法是 ES2018 引入标准的。
Promise.all
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3]);
p
的状态由p1
、p2
、p3
决定,分成两种情况。
(1)只有p1
、p2
、p3
的状态都变成fulfilled
,p
的状态才会变成fulfilled
,此时p1
、p2
、p3
的返回值组成一个数组,传递给p
的回调函数。
p.then([r1,r2,r3]=>{ console.log(r1,r2,r3) }).catch(err=>{ console.log(err) })
(2)只要p1
、p2
、p3
之中有一个被rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p
的回调函数。
原文:https://www.cnblogs.com/shiyi2009/p/14157636.html