Promise
一朝刊、Promise 是一個(gè)異步操作返回的對象,用來傳遞異步操作的消息蜈缤,
根據(jù)自己對 Promise 的理解拾氓,實(shí)現(xiàn)一個(gè)Promise :
Promise 有三種狀態(tài):Pending
初始態(tài); Fulfilled
成功態(tài)底哥; Rejected
失敗態(tài)
function Promise(executor) {
let self = this;
self.statuts = 'pending'; //等狀態(tài)
self.value = undefined; //成功的返回值
self.reason = undefined; //失敗的返回值
function resolve(value) {
if (self.statuts === 'pending') {
self.statuts = 'resolved';
self.value = value;
}
}
function reject(reason) {
if (self.statuts === 'pending') {
self.statuts = 'rejected';
self.reason = reason;
}
}
try {
executor(resolve, reject)
} catch (e) {
reject(e); //捕獲時(shí)如果發(fā)生異常咙鞍,就直接失敗
}
}
//onFufiled 成功的回調(diào)
//onRejected 失敗的回調(diào)
Promise.prototype.then = function (onFufiled, onRejected) {
let self = this;
if (self.status === 'resolved') {
onFufiled(self.value);
}
if (self.status === 'rejected') {
onRejected(self.reason);
}
}
module.exports = Promise;
來測試一下子:
let Promise = require('./Promise');
let Promise = new Promise(function (resolve, reject) {
resolve(100);
});
Promise.then(function (data) {
console.log('data:', data);
}, function (err) {
console.log('err', err);
});
//輸出:data: 100
}
Promise 實(shí)例可以多次then,當(dāng)成功后會(huì)將 then 中的成功方法按順序執(zhí)行趾徽,我們可以先將 then 中成功的回調(diào)和失敗的回調(diào)存到數(shù)組內(nèi)续滋。當(dāng)成功的時(shí)候調(diào)用成功的數(shù)組即可
self.onResolvedCallbacks = []; /* 存放then成功的回調(diào)*/
self.onRejectedCallbacks = []; /* 存放then失敗的回調(diào)*/
function resolve(value){
if(self.status === 'pending'){
self.status = 'resolved';
self.value = value;
self.onResolvedCallbacks.forEach(function (fn) {
fn();
})
}
}
function reject(reason) {
if(self.status === 'pending') {
self.status = 'rejected';
self.reason = reason;
self.onRejectedCallbacks.forEach(function (fn) {
fn();
})
}
}
復(fù)制代碼if(self.status === 'pending'){
self.onResolvedCallbacks.push(function () {
onFufiled(self.value);
})
self.onRejectedCallbacks.push(function () {
onRejected(self.reason);
})
}
手寫 AJAX
//背代碼,完整版
var request = new XMLHttpRequest()
request.open('GET', 'a/b/c?name=ff', true);
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
console.log(request.responseText);
}
}
request.send()
// 背代碼孵奶,簡化版
var request = new XMLHttpRequest()
request.open('GET', 'a/b/c?name=ff', true)
request.onload = () => console.log(request.responseText)
request.send()