自己实现一个简易版Promise
一、了解Promise
Promise
是异步编程的一种解决方案,ES6新增的一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。
Promise
有以下两个特点:
(1)Promise
的状态不受外界影响。Promise
翻译过来是承诺的意思,这个承诺会在未来有一个确切的答复,并且该承诺有三种状态,分别是:等待中pending
、已完成 resolved
、已失败rejected
。它代表一个异步操作,只有异步操作的结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
(2)Promise
一旦由等待状态变成为其他状态就永远不能更改为其他状态了。也就是说,当状态从 Pending
变为 Resolved
或者 Rejected
后,状态就不能更改了。
newPromise((resolve, reject) => {resolve('resolve')
reject('reject') // 这个reject无效
})
当我们在构造 Promise
的时候,构造函数内部的代码是立即执行的:
newPromise((resolve, reject) => {console.log(1);
resolve('resolve')
})
console.log(2);
Promise
的链式调用:
newPromise(function(resolve, reject){resolve(1);
}).then(function(data){
console.log(data);
returnnewPromise(function(resolve, reject){
resolve(2);
})
}).then(function(data){
console.log(data);
}).catch(function(err){
console.log(err);
})
Promise
很好地解决了回调地狱的问题,使代码可以变得更加简洁优雅。
Promise
也存在一些缺点:(1) 它一旦新建就会立即执行,无法中途取消;(2) 错误是需要通过回调函数捕获。
二、手写一个简易版的Promise
首先,创建三个表示状态的常量:
const PENDING = 'pending';const RESOLVED = 'resolved';
const REJECTED = 'rejected';
搭建构造函数的框架:
functionmyPromise(fn) { // 传入的是一个函数// 定义一个常量that来缓存当前的this对象
const that = this;
// 初始状态是pending
that.status = PENDING;
// 定义一个变量来保存resolve或者reject传入的值
that.param = null;
// 定义两个数组来记录异步操作之后回来执行的函数(即保存then中的回调函数,等状态改变时执行)
that.resolvedCallBacks = []; // 状态转为成功之后执行的函数
that.rejectedCallBacks = []; // 状态转为失败之后执行的函数
// 定义resolve函数
functionresolve() {
}
// 定义reject函数
functionreject() {
}
// 执行fn函数
fn();
}
下面来完善resolve
和reject
函数:
// 定义resolve函数functionresolve(param) {
// 只有状态为初始状态时才执行
if (that.status === PENDING) {
that.status = RESOLVED; // 执行之后状态改为成功
that.param = param; // 记录传入的参数
// 遍历回调函数并执行
that.resolvedCallBacks.map(function(callback){
callback && callback(that.param);
})
}
}
// 定义reject函数
functionreject(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);
})
以上是 自己实现一个简易版Promise 的全部内容, 来源链接: utcz.com/a/18611.html