Promise
是异步编程的一种解决方案,ES6新增的一个对象,用来传递异步操做的消息。它表明了某个将来才会知道结果的事件(一般是一个异步操做),而且这个事件提供统一的 API,可供进一步处理。编程
Promise
有如下两个特色:数组
(1)Promise
的状态不受外界影响。Promise
翻译过来是承诺的意思,这个承诺会在将来有一个确切的答复,而且该承诺有三种状态,分别是:等待中pending
、已完成 resolved
、已失败rejected
。它表明一个异步操做,只有异步操做的结果能够决定当前是哪种状态,任何其余操做都没法改变这个状态。缓存
(2)Promise
一旦由等待状态变成为其余状态就永远不能更改成其余状态了。也就是说,当状态从 Pending
变为 Resolved
或者 Rejected
后,状态就不能更改了。框架
new Promise((resolve, reject) => {
resolve('resolve')
reject('reject') // 这个reject无效
})
复制代码
当咱们在构造 Promise
的时候,构造函数内部的代码是当即执行的:异步
new Promise((resolve, reject) => {
console.log(1);
resolve('resolve')
})
console.log(2);
复制代码
Promise
的链式调用:异步编程
new Promise(function(resolve, reject){
resolve(1);
}).then(function(data){
console.log(data);
return new Promise(function(resolve, reject){
resolve(2);
})
}).then(function(data){
console.log(data);
}).catch(function(err){
console.log(err);
})
复制代码
Promise
很好地解决了回调地狱的问题,使代码能够变得更加简洁优雅。函数
Promise
也存在一些缺点:(1) 它一旦新建就会当即执行,没法中途取消;(2) 错误是须要经过回调函数捕获。ui
首先,建立三个表示状态的常量:this
const PENDING = 'pending';
const RESOLVED = 'resolved';
const REJECTED = 'rejected';
复制代码
搭建构造函数的框架:spa
function myPromise(fn) { // 传入的是一个函数
// 定义一个常量that来缓存当前的this对象
const that = this;
// 初始状态是pending
that.status = PENDING;
// 定义一个变量来保存resolve或者reject传入的值
that.param = null;
// 定义两个数组来记录异步操做以后回来执行的函数(即保存then中的回调函数,等状态改变时执行)
that.resolvedCallBacks = []; // 状态转为成功以后执行的函数
that.rejectedCallBacks = []; // 状态转为失败以后执行的函数
// 定义resolve函数
function resolve() {
}
// 定义reject函数
function reject() {
}
// 执行fn函数
fn();
}
复制代码
下面来完善resolve
和reject
函数:
// 定义resolve函数
function resolve(param) {
// 只有状态为初始状态时才执行
if (that.status === PENDING) {
that.status = RESOLVED; // 执行以后状态改成成功
that.param = param; // 记录传入的参数
// 遍历回调函数并执行
that.resolvedCallBacks.map(function(callback){
callback && callback(that.param);
})
}
}
// 定义reject函数
function reject(param) {
// 只有状态为初始状态时才执行
if (that.status === PENDING) {
that.status = REJECTED; // 执行以后状态改成失败
that.param = param; // 记录传入的参数
// 遍历回调函数并执行
that.resolvedCallBacks.map(function(callback){
callback && callback(that.param);
})
}
}
复制代码
执行 fn
函数时,把 resolve
和 reject
当作参数传入,捕捉到错误后执行 reject
函数
// 执行fn函数
try {
fn(resolve, reject);
} catch(e) {
reject(e);
}
复制代码
接下来实现 then
函数:
// then函数有两个参数onFulfilled, onRejected(参数为函数)
// 当前实例状态变成成功状态时,onFulfilled做为回调函数被调用
// 当前实例状态变成失败状态时,onRejected做为回调函数被调用
myPromise.prototype.then = function(onFulfilled, onRejected) {
const that = this;
// 当状态为初始状态时,把对应函数保存到对应回调函数数组中
if (that.status === PENDING) {
that.resolvedCallBacks.push(onFulfilled);
that.rejectedCallBacks.push(onRejected);
}
// 当状态为成功状态时,执行onFulfilled
if (that.status === RESOLVED) {
onFulfilled(that.param);
}
// 当状态为成功状态时,执行onFulfilled
if (that.status === REJECTED) {
onRejected(that.param);
}
}
复制代码
以上就是简易版的 Promise
实现了,最后来简单的运行一下:
new myPromise(function(resolve, reject){
resolve(1);
// reject(2);
}).then(function(data) {
console.log(data);
}, function(err) {
console.log(err);
})
复制代码