您的位置:首页 > 其它

浅谈promise(then、catch、resolve、reject、race、all、done、finally)

2017-09-05 20:49 465 查看
抽象异步处理对象以及对其进行各种操作的组件

主要类型

Constructor
构造函数

Instance Method
实例方法

Static Method
静态方法

**
promise.then(onFulfilled, onRejected)
操作之后执行回调函数。**Fulfilled为执行成功调用的函数,onRejected为执行失败调用的函数。

promise.catch(onRejected)
捕获到错误执行onRejected函数


promise状态

只能由pending到fulfilled或Rejected

状态不可逆

graph LR
Pending-->Fulfilled
Pending-->Rejected


使用
new Promise
方法创建promise对象。

.then
.then
添加promise对象的处理函数。

Promise.resolve/Promise.reject

静态方法Promise.resolve(value) 可以认为是 new Promise() 方法的快捷方式。

new Promise(function(resolve){
resolve(42);
});


promise的链式写法(chain)

function taskA() {
console.log("Task A");
}
function taskB() {
console.log("Task B");
}
function onRejected(error) {
console.log("Catch Error: A or B", error);
}
function finalTask() {
console.log("Final Task");
}

var promise = Promise.resolve();
promise
.then(taskA)
.then(taskB)
.catch(onRejected)
.then(finalTask);




then 注册onFulfilled时的回调函数

catch 注册onRejected时的回调函数

链式写法的参数传递

function doubleUp(value) {
return value * 2;
}
function increment(value) {
return value + 1;
}
function output(value) {
console.log(value);// => (1 + 1) * 2
}

var promise = Promise.resolve(1);
promise
.then(increment)
.then(doubleUp)
.then(output)
.catch(function(error){
// promise chain中出现异常的时候会被调用
console.error(error);
});




promise.all

Promis
e39f
e.all
接收一个 promise对象的数组作为参数,当这个数组里的所有promise对象全部变为resolve或reject状态的时候,它才会去调用
.then
方法。

Promise.all([request.comment(), request.people()]);


request.comment()
request.people()
会同时执行(并行执行)。

promise的结果和传递给Promise.all的数组的顺序一致。

promise.race

Promise.race
只要有一个promise对象进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理。

注:promise.race在第一个函数执行完毕后,并不会取消其他函数的执行状态,但是其余函数执行完毕之后不会再调用
.then


then与catch

.catch
也可以理解为 promise.then(undefined, onRejected),但实际使用中我们还是会将then与catch分开使用。

建议多用catch方法,少用then方法的第二个参数

function throwError(value) {
// 抛出异常
throw new Error(value);
}
// <1> onRejected不会被调用
function badMain(onRejected) {
return Promise.resolve(42).then(throwError, onRejected);
}
// <2> 有异常发生时onRejected会被调用
function goodMain(onRejected) {
return Promise.resolve(42).then(throwError).catch(onRejected);
}
// 运行示例
badMain(function(){
console.log("BAD");
});
goodMain(function(){
console.log("GOOD");
});

//输出结果
`GOOD`


使用
.then
即使 throwError 抛出了异常,onRejected 指定的函数也不会被调用。

使用
.catch
因为是链式操作,会捕获到上一步
.then
中抛出的操作。

promise中的错误捕获

const someAsyncThing = function() {
return new Promise(function(resolve, reject) {
// 下面一行会报错,因为x没有声明
resolve(x + 2);
});
};

someAsyncThing().then(function() {
console.log('everything is great');
});

setTimeout(() => { console.log(123) }, 2000);
// Uncaught (in promise) ReferenceError: x is not defined
// 123


以上代码中,someAsyncThing函数中会出现一个变量为定义的错误,然而因为错误发生在promise对象中,这个错误不会被监听到,promise之后的代码也会继续执行

也就是说promise内部的错误不会影响promise外部的代码

要想监听这个错误可使用node的unhandledRejection事件

unhandledRejection事件有两个参数

第一个为错误对象

第二个为报错的Promise实例

process.on('unhandledRejection',function (err, p) {
throw err;
});


Promise.resolve

有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用。

Promise.resolve一般有四种用法

参数是Promise实例,将直接返回这个实例

参数是个
thenable
对象,(thenable对象指的是具有then方法的对象,代码如下),会将这个对象转为 Promise 对象然后立即执行它的then方法

let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};


如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个状态为resolved的新 Promise 对象。

const jsPromise = Promise.resolve($.ajax('/whatever.json'));


Promise.resolve方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。

done()

Promise 对象的回调链,不管以then方法或catch方法结尾,要是最后一个方法抛出错误,都有可能无法捕捉到(因为 Promise 内部的错误不会冒泡到全局)。因此,我们可以提供一个done方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。

代码示例:

asyncFunc()
.then(f1)
.catch(r1)
.then(f2)
.done();


代码实现

Promise.prototype.done = function (onFulfilled, onRejected) {
this.then(onFulfilled, onRejected)
.catch(function (reason) {
// 抛出一个全局错误
setTimeout(() => { throw reason }, 0);
});
};


done都会捕捉到任何可能出现的错误,并向全局抛出。

finally()

finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。只要proise对象出现最后状态,finally方法就一定会执行。

类似于一个函数的回调。

代码示例

server.listen(0)
.then(function () {
// run test
})
.finally(server.stop);


代码实现

Promise.prototype.finally = function (callback) {
let P = this.constructor;
return this.then(
value  => P.resolve(callback()).then(() => value),
reason => P.resolve(callback()).then(() => { throw reason })
);
};


END

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: