Promise是JavaScript中为解决异步问题,结合社区已有规范,提出的一种异步编程解决方案。 在ES6中,Promise自己一个构造函数,原型链上有then、catch和finally等方法。自身的静态方法有all、race、reject和resolve等。javascript
请求态pending、完成态fulfilled、拒绝态rejected。java
一个须要记住的点:git
Promise的状态只能够由
pending ——> fulfilled
或pending——> rejected
,一旦Promise状态发生改变,也就是说一旦Promise的状态变为fulfilled或者rejected,那么它的转态便不可再变。 [image:90230504-F905-4CDC-A4BE-A5FF2FE79F33-4052-0000191F58D20B47/52d29942398343318f015c5b334766a4.png] github![]()
(function() {
function P(fn) {
var self = this;
this.fullfilleds = [];
this.faileds = [];
function resolve() {
self.fullfilled = true;
let args = Array.prototype.slice.call(arguments);
self.result = args;
if (self.fullfilleds.length) {
// 执行then方法注册的函数,真正的操做是将callbacks队列中的回调一一执行
self.fullfilleds.forEach(fn=>{
fn.apply(null, args);
})
}
}
function reject() {}
fn.call(null, resolve, reject);
}
P.prototype.then = function(fullfilled, failed) {
if (this.fullfilled) {
fullfilled.apply(null, this.result)
} else if (this.failed) {
failed(this.failed);
} else {
this.fullfilleds.push(fullfilled);
this.faileds.push(failed);
}
}
const p = new P((resolve,reject)=>{
resolve('sync');
});
p.then(d=>{
console.log(d);
});
setTimeout(()=>{
p.then(d=>{
console.log(d + 2);
})
}, 2000)
}
)()
复制代码
使用回调解决异步编程的方案是一种比较简单直接方式。编程
// demo 1
setTimeout( ()=>{
console.log("1秒钟后输出");
}, 1000);
// demo 2
Ajax.get('xxx', {}, function(data){
// DO something
});
复制代码
这种方案单层的回调还算能够,但若是回调里面又出现新的回调,产生嵌套。 像这种app
Ajax.get('xxx', {}, function(){
Ajax.get('xxx', {}, function(){
Ajax.get('xxx', {}, function(){
// do something
})
});
})
复制代码
Promise的链式调用则不存在此问题,在能够控制顺序 的前提下,能够比较直观地编写异步代码。异步
在回调函数的方案中,因为回调函数执行栈与原函数分开,致使没法捕获异常。这一点在Promise中,借助rejected,能够将错误捕获。async
不一样于回调函数,Promise借助then方法能够控制程序的执行。若是经过回调函数,调用者是不知道异步程序结束而后调用回调的。异步程序结束后,回回调函数被异步程序本身在后台默默调用,调用者失去了程序的控制权。但Promise中的then方法不存在此问题,由于then方法的调用者仍是主程序自己。ide
简单地说,async/await
是Promise的语法糖。由于async函数返回值是Promise类型,await 后面的语句吐出 的是一个Promise传给then方法的数据。异步编程
(async function(){
async function f(){
return 1;
}
let a = f();
console.log( a instanceof Promise); // true
let b = await a;
console.log(b); // 1
let c = await Promise.resolve(2);
console.log(c); // 2
})()
复制代码
相对于Promise,在处理 then 的调用链时,async/await的写法可以更清晰准确的写出代码 而且也能优雅地解决回调地狱问题。这更符合人类的线性思惟方式。
【翻译】Promises/A+规范-图灵社区 GitHub - tildeio/rsvp.js: A lightweight library that provides tools for organizing asynchronous code