Promise要点记录

2019-06-27  本文已影响0人  LuckyS007

1.什么是Promise?
Promise是抽象异步处理对象以及对其进行各种操作的组件。
2.三种类型
Constructor是其中一种:

Promise类似于 XMLHttpRequest,从构造函数 Promise 来创建一个新建新promise对象作为接口。

要想创建一个promise对象、可以使用new来调用Promise的构造器来进行实例化。

var promise = new Promise(function(resolve, reject) {
    // 异步处理
    // 处理结束后、调用resolve 或 reject
});
//可以使用then,catch实例化:
成功resolve():
promise.then(onFulfilled, onRejected)
失败reject()有两种写法,后者更直观:
promise.then(undefined, onRejected)  == promise.catch(onRejected)

3.Promise创建和处理方法:

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

###比如 Promise.resolve(42); 可以认为是以下代码的语法糖。

new Promise(function(resolve){
    resolve(42);
});
###方法 Promise.resolve(value); 的返回值也是一个promise对象,所以我们可以像下面那样接着对其返回值进行 .then 调用。

Promise.resolve(42).then(function(value){
    console.log(value);
});

5.Promise方法链

aPromise.then(function taskA(value){
// task A
}).then(function taskB(vaue){
// task B
}).catch(function onRejected(error){
    console.log(error);
});
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);
image.png

6.不管是 then 还是 catch 方法调用,都返回了一个新的promise对象。
6.1 我们说过 .catch 也可以理解为 promise.then(undefined, onRejected)
then不能进行错误处理的onRejected

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");
});
在上面的代码中, badMain 是一个不太好的实现方式(但也不是说它有多坏), goodMain 则是一个能非常好的进行错误处理的版本。
为什么说 badMain 不好呢?,因为虽然我们在 .then 的第二个参数中指定了用来错误处理的函数,但实际上它却不能捕获第一个参数 onFulfilled 指定的函数(本例为 throwError )里面出现的错误。
也就是说,这时候即使 throwError 抛出了异常,onRejected 指定的函数也不会被调用(即不会输出"BAD"字样)。
与此相对的是, goodMain 的代码则遵循了 throwError→onRejected 的调用流程。 这时候 throwError 中出现异常的话,在会被方法链中的下一个方法,即 .catch 所捕获,进行相应的错误处理。
.then 方法中的onRejected参数所指定的回调函数,实际上针对的是其promise对象或者之前的promise对象,而不是针对 .then 方法里面指定的第一个参数,即onFulfilled所指向的对象,这也是 then 和 catch 表现不同的原因。

``

2.10.2. 总结

这里我们又学习到了如下一些内容。

  1. 使用promise.then(onFulfilled, onRejected) 的话

    • onFulfilled 中发生异常的话,在 onRejected 中是捕获不到这个异常的。
  2. promise.then(onFulfilled).catch(onRejected) 的情况下

    • then 中产生的异常能在 .catch 中捕获
  3. .then.catch 在本质上是没有区别的

    • 需要分场合使用。

我们需要注意如果代码类似 badMain 那样的话,就可能出现程序不会按预期运行的情况,从而不能正确的进行错误处理。

7.使用 reject 会比使用 throw 安全
在 then 中使用reject的方法
8.then原理
在 then 中注册的回调函数可以通过 return 返回一个值,这个返回值会传给后面的 then 或 catch 中的回调函数。

而且return的返回值类型不光是简单的字面值,还可以是复杂的对象类型,比如promise对象等。
这时候,如果返回的是promise对象的话,那么根据这个promise对象的状态,在下一个 then 中注册的回调函数中的onFulfilled和onRejected的哪一个会被调用也是能确定的。

也许实际中我们可能不常使用 reject ,但是比起来不假思索的使用 throw 来说,使用 reject 的好处还是很多的。

var promise = Promise.resolve();
promise.then(function () {
    var retPromise = new Promise(function (resolve, reject) {
        // resolve or reject 的状态决定 onFulfilled or onRejected 的哪个方法会被调用
    });
    return retPromise;
}).then(onFulfilled, onRejected);
###后面的then调用哪个回调函数是由promise对象的状态来决定的

也就是说,这个 retPromise 对象状态为Rejected的时候,会调用后面then中的 onRejected 方法,这样就实现了即使在 then 中不使用 throw 也能进行reject处理了。

var onRejected = console.error.bind(console);
var promise = Promise.resolve();
promise.then(function () {
    var retPromise = new Promise(function (resolve, reject) {
       reject(new Error("this promise is rejected"));
    });
    return retPromise;
}).catch(onRejected);
//简写
var onRejected = console.error.bind(console);
var promise = Promise.resolve();
promise.then(function () {
    return Promise.reject(new Error("this promise is rejected"));
}).catch(onRejected);

推荐原文:http://liubin.org/promises-book/#promise-sequence

上一篇 下一篇

猜你喜欢

热点阅读