dahong

在JS中使用Promise-Promise链

dahong · 2017-06-17翻译 · 1073阅读 原文链接

欢迎来到 《在JS中使用 Promise》系列文章的第三篇,在 第一篇中,我们介绍了什么是Promise并且怎么来使用它,在 第二篇中,我们开始研究怎么来创建一个Promise,今天,我们来研究Promise怎么来链式调用的

发生了什么

我们已经知道能在Promise的thencatch中注册回调,但是如果注册多个回调会发生什么?

const promise = Promise.resolve(1);
promise.then(result => console.log(`I got the result: ${result}`));
promise.then(result => console.log(`And so did I: ${result}`));

两个回调都执行成功了

输出:
I got the result: 1
And so did I: 1

但是你知道吗?当你调用then的时候实际上会生成一个新的Promise,下面我们来证明下:

const promise = Promise.resolve(1);
const child1 = promise.then(result => {});
const child2 = promise.then(result => {});
console.log('Are they equal? ', child1 === child2 ? 'Yep!' : 'Nope!')
输出: 
Are they equal?  Nope!

这有一些有趣的含义,举个例子,我们来链式调用then...

const promise = Promise.resolve(1);
promise.then(result => console.log(`I got the result: ${result}`))
       .then(result => console.log(`Here is what I got: ${result}`));

我们看到第一次resolve中得到我们想要的值,但是第二次并没有

输出:
I got the result: 1
Here is what I got: undefined

为什么会这样呢?好吧,我们第一次调用then的时候会创建一个新的Promise,这个Promise resolved的值是我们第一个回调中return的值(在最后一个回调中我们看到它是undefined),我们可以利用它来实现更复杂的链式调用

在Promise之间传递数据

我们已经知道调用then会创建一个新的Promise,并且在回调中我们return的任何值都会成为这个Promise的resolve值,这意味着我们可以这样做:

const promise = Promise.resolve(1);
promise.then(result => {
            console.log(`I got the result: ${result}`);
            return result + 1;
        })
       .then(result => {
            console.log(`And so did I: ${result}`);
            return result + 1
       })
       .then(result => {
            console.log(`Me, too: ${result}`);
       });
输出:
I got the result: 1
And so did I: 2
Me, too: 3

请注意我使用了块级箭头函数而不是平常简洁的箭头函数,这是因为我们链式调用then时我们需要return一些值,如果我们使用简洁的箭头函数:

const promise = Promise.resolve(1);
promise.then(result => console.log(`I got the result: ${result}`))
       .then(result => console.log(`But I didn't: ${result}`))
       .then(result => console.log(`Me either: ${result}`));

我们得到这个结果

I got the result: 1
But I didn't: undefined
Me either: undefined

你是不是已经意识模糊了?没关系,应该的,这正是像我这种 .NET 开发人员对js箭头函数的一个模糊点,让我们用另外一个方式来重写,我们简洁的箭头函数实际上这样子的:

const promise = Promise.resolve(1);
promise.then(result => {
            return console.log(`I got the result: ${result}`);
        })
       .then(result => {
            return console.log(`And so did I: ${result}`);
       })
       .then(result => {
            return console.log(`Me, too: ${result}`);
       });

我们return了console.log的值,这个值本身就是undefined,因此我们在后面的两个Promise中得到了undefined

总结

从这篇文章中我们得到最重要的点是:我们每一次调用then都会创建一个新的Promise,如果我们从这个Promise中return了值,它相当我们用Promise.resolve(value)创建一个新的Promise 当我们从then的回调中得到一个新的Promise时,事情变得有趣了起来,这正是我们下一篇文章要说到的 😃

    9e51fdcd-257f-4e83-8f13-33f844159383|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04
相关文章