promise 理解与总结
对Promise的理解
Promise是异步编程的一种解决方案,可以获取异步操作的消息,避免了地狱回调,它比传统的解决方案回调函数和事件更合理和更强大。
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
(1)Promise的实例有三个状态:
pending
(进行中)fulfilled
(已完成)rejected
(已拒绝)
(2)Promise的实例有两个过程:
- pending -> fulfilled : resolve()
- pending -> rejected:rejecte()
特点:状态不受外界干;一旦状态改变,就不会再变,这也是promise这个名字的由来——“承诺”。
注意: 在构造 Promise
的时候,构造函数内部的代码是立即执行的。
状态的改变是通过 resolve() 和 reject() 函数来实现的,可以在异步操作结束后调用这两个函数改变 Promise 实例的状态,它的原型上定义了一个 then 方法,使用这个 then 方法可以为两个状态的改变注册回调函数。这个回调函数属于微任务,会在本轮事件循环的末尾执行。
Promise的缺点:
- 无法取消Promise,一旦新建它就会立即执行,无法中途取消。
- 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
- 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
Promise的基本用法
(1)创建Promise对象
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
。
它们是两个函数,调用后只是改变状态,并不会终结 Promise 的参数函数的执行。
const promise = new Promise(function(resolve, reject) { if (/* 异步操作成功 */){ resolve(value); // 后续代码还可以继续执行 } else { reject(error); } });
一般情况下都会使用new Promise()来创建promise对象,但是也可以使用promise.resolve
和promise.reject
这两个方法。
这两种方法是new Promise
的快捷形式,也创建一个promise对象。
(2)Promise方法
-
then()
then
方法是定义在promise原型对象上的,作用是为 Promise 实例添加状态改变时的回调函数。
promise.then( function(value){ // 成功后执行的代码 }, function(error){ // 失败后执行的代码 } );
then
方法可以接受两个回调函数作为参数,其中参数是可选的。
- 第一个回调函数是Promise对象的状态变为
resolved
时调用; - 第二个回调函数是Promise对象的状态变为
rejected
时调用。
then
方法返回的是一个新的Promise实例。因此可以采用链式写法,在then
后再调用then方法。
-
catch()
Promise对象还有一个catch方法,该方法相当于then
方法的第二个参数,指向reject
的回调函数。在执行resolve
回调函数时,如果出现错误,不会停止运行,而是进入catch
方法中。
p.then((data) => { console.log('resolved',data); },(err) => { console.log('rejected',err); } ); p.then((data) => { console.log('resolved',data); }).catch((err) => { console.log('rejected',err); });
-
finally()
finally
方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
promise .then(result => {···}) .catch(error => {···}) .finally(() => {···});
上面代码中,不管promise
最后的状态,在执行完then
或catch
指定的回调函数以后,都会执行finally
方法指定的回调函数。
finally
方法的回调函数不接受任何参数,这表明,finally
方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。finally
本质上是then
方法的特例:
promise.then( result => { // 语句 return result; }, error => { // 语句 throw error; } );
使用finally
方法,同样的功能,就不需要为成功和失败两种情况各写一次。
-
all()
Promise.all()
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3]);
它接收一个数组,数组的每一项都是一个promise
对象。当数组中所有的promise
的状态都达到resolved
的时候,all
方法的状态就会变成resolved
,如果有一个状态变成了rejected
,那么all
方法的状态就会变成rejected
。
let promise1 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(1); },2000) }); let promise2 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(2); },1000) }); let promise3 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(3); },3000) }); Promise.all([promise1,promise2,promise3]).then(res=>{ console.log(res); //结果为:[1,2,3] })
调用all
方法时的结果成功的时候是回调函数的参数也是一个数组,这个数组按顺序保存着每一个promise对象resolve
执行时的值。失败的时候,返回失败对象执行reject
的值。
-
race()
race
方法和all
一样,接受的参数是一个每项都是promise
的数组,但是与all
不同规则是,当最先执行完的事件执行完之后,就直接返回该promise
对象的值。如果第一个promise
对象状态变成resolved
,那自身的状态变成了resolved
;反之第一个promise
变成rejected
,那自身状态就会变成rejected
。
let promise1 = new Promise((resolve,reject)=>{ setTimeout(()=>{ reject(1); },2000) }); let promise2 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(2); },1000) }); let promise3 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(3); },3000) }); Promise.race([promise1,promise2,promise3]).then(res=>{ console.log(res); //结果:2 },rej=>{ console.log(rej)}; )
本文来自博客园,作者:辉太狼`,转载请注明原文链接:https://www.cnblogs.com/HuiTaiLang1216/p/15362854.html