首先强调的是“Promise”是对象,也就是说与其他JavaScript对象的用法,没有什么两样;其次,它起到代理作用(proxy),充当异步操作与回调函数之间的中介。它使得异步操作具备同步操作的接口,使得程序具备正常的同步运行的流程,回调函数不必再一层层嵌套。
Promise 对象是 CommonJS 工作组提出的一种规范,目的是为异步操作提供统一接口,简单说,它的思想是,每一个异步任务立刻返回一个Promise对象,由于是立刻返回,所以可以采用同步操作的流程。这个Promises对象有一个then方法,允许指定回调函数,在异步任务完成后调用。
前文说了Promise对象提供异步操作接口,简而言之就是:执行异步任务时返回一个Promise对象,并且Promise对象只有三种状态:
{
1.异步操作“未完成”(pending)
2.异步操作“已完成”(resolved,又称fulfilled)
3.异步操作“失败”(rejected)
}
三种状态的转换只有两种途径: 异步操作从“未完成”到“已完成” => 异步操作从“未完成”到“失败”。所以这种变化只能发生一次,一旦当前状态变为“已完成”或“失败”,就意味着不会再有新的状态变化了。因此,Promise对象的最终结果只有两种:{
- 异步操作成功,Promise对象传回一个值,状态变为
resolved
。 - 异步操作失败,Promise对象抛出一个错误,状态变为
rejected
。
}
Promise对象使用then
方法添加回调函数。then
方法可以接受两个回调函数,第一个是异步操作成功时(变为resolved
状态)时的回调函数,第二个是异步操作失败(变为rejected
)时的回调函数(可以省略)。一旦状态改变,就调用相应的回调函数。
那么promise对象是怎么生成的呢?
其实ES6提供了原生的Promise构造函数,用来生成Promise实例。下面代码创造了一个Promise实例。(跟声明对象new一样的方式)
var promise = new Promise(function(resolve, reject) {
// 异步操作的代码 if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
resolve
函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从Pending
变为Resolved
),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject
函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从Pending
变为Rejected
),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise实例生成以后,可以用then
方法分别指定Resolved
状态和Reject
状态的回调函数。
po.then(function(value) {
// success
}, function(value) {
// failure
});
Promise 封装的代码肯定是同步的, 那么这个 then 的执行是异步的吗? 可以通过以下这个有意思的小例子可以知道Promise对象的执行顺序
setTimeout(function() {
console.log(1)
}, 0);
new Promise(function executor(resolve) {
console.log(2);
for( var i=0 ; i<10000 ; i++ ) {
i == 9999 && resolve();
}
console.log(3);
}).then(function() {
console.log(4);
});
console.log(5); ==》》2 3 5 4 1
以上是我看一篇博文里的一段代码(出自),可以参考一下奥