对于 Chaining Promises 的理解,不知道对不对,欢迎纠错。

2015-07-30 21:22:10 +08:00
 haozhang

我对于链式Promise的理解是这样,不知道对不对:

首先.then和.catch都会返回一个新的promise对象,这个second promise对象的
状态是根据第一个promise对象的回调函数执行的情况来决定的。如果第一个promise对象的回调函数(不管是fulfillment handler还是rejection handler都一样)正常执行,没有抛出错误,则second promise对象的状态变成fulfilled,并且使之变成的fulfilled状态的值就是前一个promise对象的回调函数中返回的值。

let p1 = new Promise((resolve, reject) => {
    resolve(42);
});

p1
    .then(
        (value) => {
            console.log(value); // 42
        }
    )
    .then(
        (value) => {
            console.log(value); // undefined
        }
    );

上面代码的执行结果如下:
42
undefined

而如果在第一个promise对象的回调函数中抛出了错误,则.then方法返回的second promise对象的状态就变成了rejected,并且使之变成rejected状态的值就是上一个promise对象的回调函数中抛出的错误。

var p1 = new Promise((resolve, reject) => {
    reject(new Error("p1 error"));
});

p1
    .then(
        (value) => { 
            console.log(value);     
        },
        (error) => { 
            console.log(error); // [Error: p1 error]
            throw new Error("2"); 
        }
    )
    .then(
        (value) => { 
            console.log(value); 
        },
        (error) => { 
            console.log(error); // [Error: 2]
        }
    );

上面代码的执行结果如下:
[Error: p1 error]
[Error: 2]

当然,在第一个promise对象的回调函数中还能够返回一个promise对象,记这个promsie对象为A,则.then方法返回的second promise对象的状态就跟随这个A来了:

var p1 = new Promise((resolve, reject) => {
    resolve(1);
});

p1
    .then(
        (value) => {
            console.log(value); // 1
            return new Promise((resolve, reject) => {
                reject(new Error("promsie A was rejected"));
            });
        }
    )
    .then(
        (value) => {
            // never called
        },
        (error) => {
            console.log(error); // [Error: promsie A was rejected]
        }
    );

上面代码的执行结果如下:
1
[Error: promsie A was rejected]

然后所有的链式调用都遵循上面的规则,不管链式有多长。再强调一下:对调函数包括fulfillment handler和rejection handler,都是遵守上面的规则的。

Promise对象可以添加无数的回调函数,只要一改变状态,就开始执行添加给它的回调函数,并且执行回调函数的顺序就是添加的顺序:

var p1 = new Promise((resolve, reject) => {
    resolve(1);
});

p1
    .then(
        (value) => {console.log("the first fulfillment handler", value)}
    );


p1
    .then(
        (value) => {console.log("the second fulfillment handler", value)}
    );


p1
    .then(
        (value) => {console.log("the third fulfillment handler", value)}
    );

上面代码的执行结果如下:
the first fulfillment handler 1
the second fulfillment handler 1
the third fulfillment handler 1

要注意的是上面的写法和链式的写法(3个连续的.then)的意义是不一样的。

我的理解就是这些,不知道对不对,欢迎纠错。

3416 次点击
所在节点    Node.js
12 条回复
haozhang
2015-07-30 21:23:21 +08:00
haozhang
2015-07-30 23:20:43 +08:00
没人鸟我...
czheo
2015-07-30 23:24:27 +08:00
基本正确。补充一点
1. then的callback既可以返回一个Promise,也可以返回一个value
2. 如果返回Promise,这个Promise的状态会chain 给下一个then
3. 如果返回value,这个value会传给下一个then的callback
haozhang
2015-07-30 23:27:54 +08:00
@czheo 你补充的点我都有说啊。
czheo
2015-07-30 23:30:38 +08:00
因为你的callback都没有返回值,唯一一个返回的是一个Promise,所以。。。可能是我看漏了。
我看你的理解基本没问题。
haozhang
2015-07-30 23:34:33 +08:00
@czheo 函数不是默认返回undefined嘛,→_→
lujiajing1126
2015-07-30 23:36:39 +08:00
promise-spec是标准。。所有实现都是按照标准来的。。

说这么多还不如看看标准和实现
haozhang
2015-07-30 23:39:56 +08:00
ysmood
2015-07-31 06:25:22 +08:00
@haozhang 读读这篇,或许会有帮助你理解 promise: https://github.com/ysmood/yaku/blob/master/docs/lazyTree.md

然后打个硬广 https://github.com/ysmood/yaku
这个库的异常处理机制在业界应该是最前沿的之一,对初学者会很友好。
haozhang
2015-07-31 07:26:56 +08:00
@ysmood →_→ 嗯
hanan321
2015-07-31 10:55:38 +08:00
以前写过一个promise练手 https://github.com/hanan198501/promise
xieranmaya
2015-08-07 10:01:28 +08:00
https://promisesaplus.com/
请看标准,讲的非常详细
最近还实现了一个

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/209677

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX