Promise是个什么鬼?

Javascript中的神器

2015 年 6 月,ECMAScript 6 的正式版 终于发布了。ECMAScript 是 JavaScript 语言的国际标准,JavaScript 是 ECMAScript 的实现。ES6 的目标是使得 JavaScript 语言可以用来编写大型的复杂的应用程序,成为企业级开发语言。Promise 就是ES6提供的原生对象,简单说就是一个容器,里面保存着某个未来才会结束的事件的结果从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

我们先来写个简单的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
var promise = new Promise(function(resolve, reject) {
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});

promise.then(function(value) {
// success
}, function(value) {
// failure
});

Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 方法和 reject 方法。

如果异步操作成功,则用 resolve 方法将 Promise 对象的状态,从「未完成」变为「成功」(即从 pending 变为 resolved);

如果异步操作失败,则用 reject 方法将 Promise 对象的状态,从「未完成」变为「失败」(即从 pending 变为 rejected)。

有人一下就看明白了,这不就是做了一个异步回调嘛,我不用它也可以实现

1
2
3
4
5
6
7
8
9
10
11
12
13
function runAsync(resolve,reject){
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
}

runAsync(function(data){
console.log(data);
},function(error){
console.log(error);
});

那么问题来了,有多层回调该怎么办?如果callback也是一个异步操作,而且执行完后也需要有相应的回调函数,该怎么办呢?总不能再定义一个callback2,然后给callback传进去吧。而Promise的优势在于,可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作

从表面上看,Promise只是能够简化层层回调的写法,而实质上,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多。

在上面的例子中我们介绍了resolve、reject、then的用法,Promise对象还有其它的一些常用API:

catch的用法,这与try/catch语句有相同的功能。
all的用法,提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。
race的用法,它与all方法类似,all方法的效果实际上是「谁跑的慢,以谁为准执行回调」,那么race方法就是「谁跑的快,以谁为准执行回调」。