Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。简单来说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作的结果)
简介 ECMAscript 6 原生提供了 Promise 对象。
Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。简单来说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作的结果)
Promise 对象的基本语法:
1 2 3 4 var promise = new Promise (function (resolve, reject ) { });
特点
对象的状态不受外界影响
Promise 对象表示一个异步操作,有三种状态
pending: 初始状态
fulfilled: 操作成功
rejected: 操作失败
一旦状态改变,就不会再变,状态就凝固了
列如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var promise = new Promise (function (resolve, reject ) { resolve ('success' ) console .log ('after resolve' ) reject ('error' ) }); promise.then (result => { console .log (result); }); promise.catch (result => { console .log (result); }) after resolve success Promise { <state>: "fulfilled" , <value>: "success" }
resolve 后面的语句其实是可以执行的。那么为什么 reject 的状态信息在下面没有接受到呢?这就是 Promise 对象的状态凝固特点。new 出一个 Promise 对象时,这个对象的起始状态就是 pending 状态,再根据 resolve 或 reject 返回 fulfilled 状态或 rejected 状态。
传递回调 Promise 对象可以调用 promise.then() 方法,传递 resolve , reject 方法的回调。
1 2 3 4 5 6 promise.then (onFulfilled, onRejected) promise.then (onFulfilled) promise.then (null ,onFulfilled) promise.then (onFulfilled).catch (onRejected)
链式调用 我们来执行一段代码
1 2 3 4 5 6 7 8 9 10 11 12 13 let p = new Promise ((resolve,reject ) => { reject ('reject' ); }); let resultP = p.then (null ,result => { console .log (result); }); console .log (resultP);Promise { <state>: "pending" }reject
js 的执行顺序就是这样,同步->异步->回调,在同步执行的时候,Promise 对象还处于 pending 的状态,也说明了这个 then 返回的是一个 Promise 对象。
而且必须在then里面给一个返回值,才能继续调用,否则undefined。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 let p = new Promise ((resolve,reject ) => { reject ('error' ); }); let resultP = p.then (null ,result => { console .log (result); return 123 ; }); resultP.then (tmp => { console .log (tmp); }) error 123
Promise.resolve() 将现有对象转为 Promise 对象的快捷方式。
传递一个普通的对象:
1 2 3 4 5 6 7 8 9 let p1 = Promise .resolve ({name :'l1n6yun' ,age :'18' });p1.then (result => { console .log (result); }); Object { name : "l1n6yun" ,age :"18" }
如果是Promise对象呢,直接返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 let p = new Promise ((resolve,reject ) => { setTimeout (() => { resolve ('success' ); },500 ); }); let pp = Promise .resolve (p);pp.then (result => { console .log (result); }); console .log (pp == p);true success
Promise.reject() 快速的获取一个拒绝状态的 Promise 对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 let p = Promise .reject (123 );console .log (p);p.then (result => { console .log (result); }).catch (result => { console .log ('catch' ,result); }) Promise { <rejected> 123 }catch 123
Promise.all() Promise.all() 方法用于对多个 Promise 实例包装成一个新的 Promise 实例。
1 2 3 4 5 6 7 8 9 10 11 let p1 = Promise .resolve (123 );let p2 = Promise .resolve ('hello' );let p3 = Promise .resolve ('success' );Promise .all ([p1,p2,p3]).then (result => { console .log (result); }) Array (3 ) [ 123 , "hello" , "success" ]
成功之后就是数组类型,但所有状态都是成功状态才可以返回数组吗。如果其中有一个对象状态为 reject 就返回 reject 的状态值。
1 2 3 4 5 6 7 8 9 10 11 12 13 let p1 = Promise .resolve (123 );let p2 = Promise .resolve ('hello' );let p3 = Promise .resolve ('success' );let p4 = Promise .reject ('error' );Promise .all ([p1,p2,p4]).then (result => { console .log (result); }).catch (result => { console .log (result); }); error
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function sleep (wait ) { return new Promise ((res,rej ) => { setTimeout (() => { res (wait); },wait); }); } let p1 = sleep (500 );let p2 = sleep (500 );let p3 = sleep (1000 );Promise .all ([p1,p2,p3]).then (result => { console .log (result); });
Promise.race() Promise.race() 同样是键多个 Promise 实例包装成一个新的 Promise 实例。
和 all 同样接受多个对象,不同的是 race 接受的对象中,哪个对象返回的快就返回哪个对象。
就如race直译的赛跑这样。如果对象其中有reject状态的,必须catch捕捉到,如果返回的够快,就返回这个状态。race最终返回的只有一个值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 function sleep (wait ) { return new Promise ((res,rej ) => { setTimeout (() => { res (wait); },wait); }); } let p1 = sleep (500 );let p0 = sleep (2000 );Promise .race ([p1,p0]).then (result => { console .log (result); }); let p2 = new Promise ((resolve,reject ) => { setTimeout (()=> { reject ('error' ); },1000 ); }); Promise .race ([p0,p2]).then (result => { console .log (result); }).catch (result => { console .log (result); }); 500 error
异常处理
錯誤處理的聲音實在安靜,安靜得聽不見 from Nolan Lawson
当 promise 被明确拒绝时,会发生拒绝;但是如果是在构造函数回调中引发的错误,则会隐式拒绝。
为什么说安静,一个例子, Promise 内部的错误外界用 try-catch 捕捉不到
1 2 3 4 5 6 7 8 try { let p = new Promise ((resolve, reject ) => { throw new Error ("I'm error" ); }); }catch (e) { console .log ('catch' ,e); }
结果什么都没打印。 但是抛出的错误可以通过catch来捕捉:
1 2 3 4 5 6 7 8 9 10 11 12 13 let p = new Promise ((resolve, reject ) => { throw new Error ("I'm error" ); }); p.catch (result => { console .log (result); });
这样就捕捉到错误。所以:
建议 在 Promise 的链的尾部必须要有个catch接着。