Promise对象解析及其用法 |
您所在的位置:网站首页 › 返回的promise对象如何使用 › Promise对象解析及其用法 |
Promise
Promise的含义 Promise是异步编程的一种解决方案,比传统的解决方案----回调函数和事件----更合理且更强大。所谓的Promise,简单来说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个一步操作)的结果。从语法上来说,promise是一个对象,从他可以获取异步操作的消息。Promise提供统一的API,各种异步操作都可以用同种的方法进行处理。有了Promise对象就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。 Promise对象有以下两个特点: 1、对象的状态不受外界影响。Promise对象代表一个异步操作,有3种状态:Pending(进行中)、Fulfilled(已成功)和Rejected(已失败)。只有异步操作的结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。(promise:英译“承诺”,即其他手段无法改变)。 2、一旦状态改变就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变只有两种可能:从Pending变为Fulfilled和从Pending变为Reject。只要这两种情况发生,状态就凝固了,不会再变,而是一直保持这个结果,这是就称为Resolved(已定型)。就算改变已经发生,再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同。事件的特点是,如果错过了他,再去监听是得不到结果的。 Promise的缺点 1、无法取消Promise,一旦新建它就会立即执行,无法中途取消。 2、如果不设置回调函数,Promise内部跑出的错误不会反应到外部。 3、当处于Pending状态时,无法得知目前进展到了哪一个阶段(刚刚开始还是即将完成) 基本用法 Promise实例 var promise = new Promise (function (resolve, reject)) { // ... some code if(/* 异步操作成功 */){ resolve(value) } else { reject(error) } } //第一种写法 promise.then( function( result ) { // result ==上面的value }).catch(function (error){ // error==上面的error }) 或者 promise.then( result => console.log(result)) .catch( error => console.log(error )) //第二种写法 promise.then(function( result ) { // result ==上面的value },function (error){ // error==上面的error })注意:调用resolve或reject并不会终结Promise的参数函数执行。一般来说,调用resolve或reject以后,Promise的使命就完成了,最好在他们前面加上return,这样就不会产生意外。 new Promise((resolve,reject) =>{ resolve(1); console.log(2); }).then(r => { console.log(r); }); //2 //1 new Promise((resolve,reject) =>{ return resolve(1); console.log(2); }).then(r => { console.log(r); }); //1注意:如果p1和p2都是Promise的实例,但是p2的resolve的方法将p1作为参数,即一个异步操作的结果是返回另一个异步操作的。(p1的状态就会传递给p2); var p1 = new Promise(function (resolve, reject) { setTimeout(() => reject(new Error('fail')),3000); }); var p2 = new Promise(function (resolve, reject) { setTimeout(() => resolve(p1,3000)); }) p2.then(r=>console.log(r)).catch(r=>console.log(r)); //Error:failPromise.prototype.then() Promise实例具有then方法,即then方法是定义在原型对象Promise.prototype上的。then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Reject状态的回调函数。Promise还可以做更多的事情,比如,有若干个异步任务,需要先做任务1,如果成功后再做任务2,任何任务失败则不再继续并执行错误处理函数。要串行执行这样的异步任务,不用Promise需要写一层一层的嵌套代码。有了Promise,我们只需要简单地写: job1.then(job2).then(job3).catch(handleError); //其中,job1、job2和job3都是Promise对象。Promise.prototype.catch() Promise.prototype.catch()方法是.then(null,rejection)的别名,用于指定发生错误时的回调函数。 p.then((val) => console.log("fulfilled:",val)).catch((err) =>console.log('rejected',err)); //等同于 p.then((val) => console.log("fulfilled:",val)).then(null,(err) =>console.log('rejected',err));注意:reject方法的作用等同于抛出的错误。如果Promise状态已经resolved,再抛出出错误是无效的。 一般来说不要在then方法中定义Rejected状态的回调函数(即then的第二个参数),而应总是使用catch方法。 Promise.all() 除了串行执行若干异步任务外,Promise还可以并行执行异步任务。 试想一个页面聊天系统,我们需要从两个不同的URL分别获得用户的个人信息和好友列表,这两个任务是可以并行执行的,我们可以用Promise.all()实现。 var p1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, 'P1'); }); var p2 = new Promise(function (resolve, reject) { setTimeout(resolve, 600, 'P2'); }); // 同时执行p1和p2,并在它们都完成后执行then: Promise.all([p1, p2]).then(function (results) { console.log(results); // 获得一个Array: ['P1', 'P2'] });Promise.race() 有些时候,多个异步任务是为了容错。比如,同时向两个URL读取用户的个人信息,只需要获得先返回的结果即可。这种情况下,用Promise.race()实现: var p1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, 'P1'); }); var p2 = new Promise(function (resolve, reject) { setTimeout(resolve, 600, 'P2'); }); Promise.race([p1, p2]).then(function (result) { console.log(result); // 'P1' });由于p1执行较快,Promise的then()将获得结果'P1'。p2仍在继续执行,但执行结果将被丢弃。 Promise.done() 无论Promise对象的回调链以then方法还是catch方法结尾,只要最后一个方法抛出错误,都有可能无法捕捉到(因为Promise内部的错误不会冒泡到全局)。为此,我们可以提供一个done方法,他总是处于回调链的尾端,保证抛出任何可能出现的错误。 asyncFunc().then(f1).catch(r1).then(f2).done(); //他的实现代码 Promise.prototypr.done = function (onFulfilled, onRejected) { this.then(onFulfilled, onRejected).catch(function (reason) { //抛出一个全局错误 setTimeout(() => {throw reason },0); }); };done方法可以像then方法那样使用,提供Fulfilled和Rejected状态的回调函数,也可以不提供任何参数。但不管怎样,done方法都会捕捉到任何可能出现的错误,并向全局抛出。 Promise.finally() finally方法用于指定不管Promise对象最后状态如何都会执行的操作。它与done方法的最大区别在于,他接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。 server.listen(0).then(function (){ //return test }).finally(server.stop);
|
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |