在实现promise之前,先简单的回顾一下promise
Promise 对象有以下两个特点:
1、对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:
- pending: 初始状态,不是成功或失败状态。
- fulfilled: 意味着操作成功完成。
- rejected: 意味着操作失败。
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。
2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
Promise实现ajax操作
function ajax(URL) {
return new Promise(function(resolve, reject) {
let req = new XMLHttpRequest();
req.open('GET',URL, true);
req.onload = function () {
if(req.status == 200) {
resolve(req.responseText);
}
else {
reject(new Error(req.statusText));
}
};
req.onerror = function() {
reject(new Error(req.statusText));
};
req.send();
});
}
let URL = "try/ajax/testpromise.php";
ajax(URL).then(function onFulfilled(value) {
document.write('内容是: ' + value);
}).catch(function onRejected(error) {
document.write('错误: ' + error);
});
从上面的例子可以看出来,promise的构造函数接受一个参数,是函数,并且传入两个参数: resolve, reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数,用比较标准的术语来说就是, resolve回调时,promise的状态是fulfilled,reject是将Promise的状态置为rejected
简单的回忆了一下promise之后,我们就来自己实现promise
promise的简单实现
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
function MyPromise(fn) {
const that = this
this.state = PENDING //初始状态为pending
this.value = null //初始值为空
//用于保存then中的回调,因为当执行完Promise时状态可能还是等待,这是应该把回调函数中的值存储下来
that.resolvedCallbacks = []
that.rejectedCallbacks = []
//判断两个函数是否都在等待中
function resolve(value) {
if(that.state == PENDING) {
that.state = RESOLVED
that.value = value
//遍历回调数组并执行
that.resolvedCallbacks.map(cb=>cb(that.value))
}
}
function reject(value) {
if(that.state == PENDING) {
this.state = REJECTED
that.value = value
that.rejectedCallbacks.map(cb=>cb(that.value))
}
}
try {
fn(resolve, reject)
}catch(e){
reject(e)
}
}
//then函数的实现
MyPromise.prototype.then = function(onFulfilled,onRejected) {
const that = this
//判断是否为函数类型,因为这两个参数是可选参数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v=>v
onRejected = typeof onRejected === 'function' ? onRejected : e=> throw e
//当状态不是等待态,就去执行相应的函数。如果状态是等待态,就往回调函数中push
if(this.state == PENDING) {
this.resolvedCallbacks.push(onFulfilled)
this.rejectedCallbacks.push(onRejected)
}
if(this.state === RESOLVED) {
onFulfilled(that.value)
}
if(this.state === REJECTED) {
onRejected(that.value)
}
}