約束の例:
var getJSON = function(url) {
var promise = new Promise(function(resolve, reject) {
// XHR对象发现ajax请求
var client = new XMLHttpReqeust();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
function hanlder(){
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
});
return promise;
}
getJSON("/posts.json").then(function(json) {
console.log("Content: " + json);
}, function(error) {
console.error("出错了!', error);
});
上記コール新しい約束、関数の伝達関数(解決は、リジェクト)場合、この関数は、実行仕様exectorで言及され
、従ってexectorアクチュエータを通過する必要がある:まず:
function Promise(exector) {
//...
}
約束は、内部exectorの効果を決定する:
ネイティブexectorに見られるように、第1リジェクト及び第2の代表の成功または失敗のために解決し、2つのパラメータを渡します。
function Promise(exector) {
let self = this;
this.value = undefined;
this.reason = reason;
// 执行成功
function resolve(value) {
self.value = value;
}
// 执行失败
function reject(reason) {
self.reason = reason;
}
exector(resolve, reject);
}
状態を追加:
実行の約束が可逆的ではない、それは、解決に成功した当初は、パディングとして、その状態の状況を記録する必要がある、それは拒否することができませんでした
function Promise(exector) {
let self = this;
this.status = "padding";
this.value = value;
this.reason = reason;
// 成功
function resolve(value) {
if(self.status === "padding") {
self.value = value;
self.status = "resolved";
}
}
// 失败
function reject(reason) {
if(self.status === "padding") {
self.reason = reason;
self.status = "reject";
}
}
// 对异常的处理
try {
exector(resolve, reject);
} catch(e) {
reject(e)
}
}
次に、本方法は、プロトタイプを追加:
プロミスの使用例注次いで、上記で定義されたプロトタイププロミス方法に追加することができ、p.then(onFulfilled、onRejected)です。
Promise.prototype.then = function(onFulfilled, onRejected) {
let self = this;
if(this.status === "resolved") {
onFulfilled(self.value);
}
if(this.status === "rejected") {
onRejected(self.value);
}
}
非同期操作を完了するために2つの新しい配列:
約束は、上記のように調製呼び出しは同期されているが、一般的に約束非同期的に使用するので、約束やプロトタイプに変更する必要がある。
状態では、非同期の場合、パディング、コールバック関数fnは、配列に格納されました!
function Promise(exector) {
let self = this;
this.status = "padding";
this.value = undefined;
this.reason = undefined;
// 存储then中成功的回调函数
this.onResolvedCallbacks = [];
// 存储then中失败的回调函数
this.onRejectedCallbacks = [];
// 成功执行
function resolve(value) {
if(self.status === "padding") {
self.value = value;
self.status = "resolved";
// 成功后遍历then中成功的所有回调函数
self.onResolvedCallbacks.forEach(fn => fn());
}
}
// 失败执行
function reject(reason) {
if(self.status === "padding") {
self.reason = reason;
self.status = "rejected";
// 失败后遍历then中失败的所有回调函数
self.onRejectedCallbacks.forEach(fn => fn());
}
}
// 对异常进行处理
try {
exector(resolve, reject);
} catch(e) {
reject(e)
}
}
// Promise.prototype.then
Promise.prototype.then = function(onFulfilled, onRejected) {
let self = this;
// 成功
if (this.status === "rejected") {
onFulfilled(self.value);
}
// 失败
if (this.status === "resolved") {
onRejected(self.reason);
}
// padding
if (this.status === "padding") {
// 推进onResolvedCallbacks数组
this.onResolvedCallbacks.push( () => {
onFulfilled(self.value);
})
this.onRejectedCallbacks.push( () => {
onRejected(self.reason);
})
}
}
リファレンス「ES6標準入門」(第3版)P276
参照https://www.jianshu.com/p/4b126518c26d