聊一聊看似简单的Promise.prototype.then()方法

2020-08-05T21:59:57
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

Proise实例的then方法是定义在原型对象Promise.prototype上的,它的作用是为Promise实例添加状态改变时的回调函数。

该方法可以接收两个回调函数作为参数,其中第二个回调函数是可选的。第一个回调函数是Promise对象的状态变为Resolved时调用,第二个回调函数是Promise对象的状态变为Rejected时调用。

下面从以下几点进行说明:

  1. then 方法返回的是一个Promise实例,但是需要注意的是并不是原来调用它的那个Promise实例而是一个新的Promise实例。

    下面用代码来说明:

    let promise = new Promise( function (resolve, reject) {
        resolve();
        console.log("promise");
    });
    
    let promise_then = promise.then(function () {
     console.log("promise_then");    
    });
    
    promise_then.then(function () {
        console.log("promise_then_then")
    })
    
    // 运行结果:
    promise
    promise_then
    promise_then_then

    最先打印出promise的原因是then方法的回调函数要在所有同步任务执行完后再执行,所以会先执行console.log("promise")然后再去执行下面then方法的回调函数。

    当程序执行到第6行结束时,promisepromise_then的状态如下图所示:

可见then方法返回的是一个新的promise实例,并且此时promise_then的状态为pending

当执行完第8行时,promisepromise_then的状态如下图所示:


可见此时promise_then的状态变为resolved,也就是说只要then方法中的程序正常执行完不报错,返回实例的状态就变为resolved(这个地方原因不是很清楚,如果有明白的,欢迎留言告知,谢谢哦)。

这个时候再往下执行promise_then.then就会打印出promise_then_then

上面的代码等价于

// ES5写法
let promise = new Promise( function (resolve, reject) {
    resolve();
    console.log("promise");
});
promise.then(function () {
 console.log("promise_then");    
}).then(function () {
    console.log("promise_then_then")
});

// ES6写法
let promise = new Promise( (resolve, reject) => {
    resolve();
    console.log("promise");
});
promise.then(
    () => console.log("promise_then")    
).then( 
    () => console.log("promise_then_then")
);
  1. then 方法中前一个回调函数的返回值可以传递给下一个回调函数。


    1. 前一个回调函数的返回值是一个非promise实例时,比较简单,看一下下面的代码就很容易理解。
    let promise = new Promise( function (resolve, reject) {
        resolve();
    });
    promise.then(function () {
     return "aaa"; 
    }).then(function (data) {
        console.log(data);
    });
    // 输出结果
    "aaa"

1.  当前一个回调函数的返回值是一个promise实例时,下一个then方法的执行情况要根据这个promise实例的状态来执行。
    
    用下面的代码来解释一下:
    

```
// 如果形参是'Resolved' -> 状态为‘Resolved’的promise实例
// 如果形参是'Rejected' -> 状态为‘Rejected’的promise实例
function createPromise(status) { 
    var p = new Promise(function (resolve, reject) {
        if (status === "Resolved") {
            resolve()
        } else {
            reject();
        }
    });
    return p;
}

createPromise("Resolved").then(function () {
    return createPromise("Rejected"); // 返回的promise实例的状态是“Rejected”
}).then(function () {
    console.log("前一个回调函数的返回值promise实例的状态是'Resolved'");
}, function () {
    console.log("前一个回调函数的返回值promise实例的状态是'Rejected'");
});
// 输出结果
"前一个回调函数的返回值promise实例的状态是'Rejected'"

createPromise("Resolved").then(function () {
    return createPromise("Resolved"); // 返回的promise实例的状态是“Resolved”
}).then(function () {
    console.log("前一个回调函数的返回值promise实例的状态是'Resolved'");
}, function () {
    console.log("前一个回调函数的返回值promise实例的状态是'Rejected'");
});
// 输出结果:
"前一个回调函数的返回值promise实例的状态是'Resolved'"
```

根据上面代码的输出结果可以清晰地看到后一个回调函数的执行情况是根据前一个回调函数返回的promise的状态来执行的,如果返回的promise实例的状态为`Resolved`,那么就执行第一个函数,如果返回的promise实例的状态为`Rejected`,那么就执行第二个函数。

完,如果不恰当之处,欢迎指正哦 。
扫一扫关注公众号添加购物返利助手,领红包
当前页面是本站的「Baidu MIP」版。发表评论请点击:完整版 »
因本文不是用Markdown格式的编辑器书写的,转换的页面可能不符合MIP标准。