简单理解 Promise

promise

以前学习ES6的Promise总是似是而非,当时好像懂了,但是实际遇到时总有这样或者那样的疑惑。直到我看到了一篇 Jecelyn Yeen 的分享。

(一)理解 Promise

举个简单的例子:
想象一下你是一个孩子。你老妈承诺下周给你买个新手机。你【不知道】你老妈会不会兑现承诺,你老妈可以信守承诺给你买个新手机,但是如果她不高兴的话,也可以让你滚蛋不买了。

这就是一个Promise,一个 Promise 有三种状态,分别是:

  1. 待定(pending),下周之前你不知道会不会得到一个新手机;
  2. 兑现承诺(resolve),你老妈兑现承诺给你买了一个新手机;
  3. 违背承诺(reject),你老妈很不开心,让你滚蛋。

(二)创建一个 Promise

我们把上面的例子转换成 JS 就是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let isMomHappy = true;

let willIGetNewPhone = new Promise(
(resolve, reject) => {
if (isMomHappy) {
let phone = {
brand: 'Apple',
color: 'white'
}
//老妈很高兴,买了新手机给你,
//这时你拿到了手机,知道了手机的牌子和颜色
resolve(phone);
} else {
let reason = new Error('Mom is not happy.');
//老妈拒绝了你,你从老妈的眼神中读出了原因--“我很不高兴,别来惹我”
reject(reason);
}
}
)

这段代码是不是很有表现力~

  1. 我们有一个布尔值isMomHappy,来表示你老妈是否开心;
  2. 我们有一个Promise对象willIGetNewPhone。这个 Promise 可以是 resolve (你老妈给了你一个新手机),也可以是 reject (你老妈不开心并拒绝给你新手机)。
  3. 还有一个标准的语法去定义一个新的Promise,参考MDN documentation
    看下面的代码:
    1
    2
    //promise syntax look like this
    new Promise(/* executor*/ (resolve, reject) => { ... });

(三)玩转 Promise

现在我们有了 Promise,咱们就开始玩一玩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
// call our promise
let askMom = () => {
willIGetNewPhone
.then((fulfilled) => {
// yay, you got a new phone
console.log(fulfilled);
//output: {brand: 'Apple', color: 'white'}
}, (error) => {
// oops, mom don't buy it
console.log(error.message);
// output: 'Mom is not happy.'
});
};
askMom();
  1. 我们有一个函数askMom()。在这个函数中我们使用了之前定义的 Promise willIGetNewPhone
  2. 我们的 Promise ,到了兑现诺言的时间时,无论老妈是信守还是违背承诺,我们都会做出相应的反应,.then()(的第一个参数处理信守承诺的结果(从resolve(phone)拿到了新手机),第二个参数处理违背承诺的结果(从reject(reason)拿到了老妈拒绝你的理由)。

(四)链接 Promise

Promise
都是可以链接的。

比如说,你承诺给你的朋友说,拿到新手机就给他玩玩,让他过过瘾。

这又是另外一个 Promise 了,转换成代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
let showOff = (phone) => {
let message = `Hey friend, i have a new ${phone.brand} ${phone.color} phone`;
return new Promise (
(resolve, reject ) => {
resolve(message);
}
);
};

let askMom = () => {
willIGetNewPhone
.then(showOff)
.then((fulfilled) => {
// yay, you got a new phone
console.log(fulfilled);
//output: {brand: 'Apple', color: 'white'}
}, (error) => {
// oops, mom don't buy it
console.log(error.message);
// output: 'Mom is not happy.'
});
};
askMom();

(五) Promise 都是异步的

为什么?因为生活就是不等人的,JavaScript也是!

你不会说因为你老妈承诺你一周后给你一个新手机,然后就不去玩了,干等一星期对吧?

这就是异步调用,代码将无阻塞运行或等待结果。任何需要等 Promise 的行为都应该放在 .then() 里。