promise理解
promise的意思是承諾。承諾理解為某個時候一些條件滿足後,會兌現一件事情。
//為了方便理解我編一個小故事
//先假裝我有一個女朋友
//她承諾如果她爸媽不回來就給我就可以去幫她修電腦 否則...
let promise = new Promise(function (success,fail) {
//她說三秒後會告訴我今晚爸媽回不回來
let herParentBack = Math.random() > 0.5 ? true : false;
setTimeout(function(){
if(herParentBack){
success('我馬上過來來幫你修你電腦');
}else{
fail('你要早點休息');
}
},3000);
});
//第一個函式接收sucess函式傳來的成功資訊
//第二個函式接收fail函式傳來的失敗資訊
promise.then(function (sucessMsg) {
console.log(sucessMsg);
},function (fail) {
console.log(failMsg);
})
//我馬上過來幫你修電腦
複製程式碼
new Promise會傳入一個回撥函式,會伴著物件建立被立即呼叫。 這個function是承諾的主體內容。一般我們會做一些判斷或者非同步請求。(在這裡要等女友回訊息,我想好怎麼回答她。)
promise.then方法在promise執行了success或fail後會執行對應的成功失敗方法。 (這裡理解為吧想好告訴她)
promise實現
根據promis規範promise Promise/A
Promise設定了三個狀態,'pending'、'resolved'、'rejected'。
//Promise物件設定初始狀態
function Promise(callback) {
var self = this;
//預設為等待狀態
self.status = 'pending';
self.value = undefined;
self.reason = undefined;
//用陣列來儲存成功函式
self.onResolvedCallBacks = [];
self.onRejectedCallbacks = [];
function resolve(value){
if(self.status === 'pending'){
//設定為成功狀態
self.status = 'resolved';
self.value = value;
self.onResolvedCallBacks.forEach(item=>item(self.value));
}
}
function reject(reason) {
if(self.status === 'pending'){
//設定為失敗狀態
self.status = 'rejected';
self.reason = reason;
self.onRejectedCallbacks.forEach(item=>item(self.reason));
}
}
callback(resolve,reject);
//呼叫Promise回撥函式
}
module.exports = Promise;
複製程式碼
增加Promise.then方法
//根據Promise狀態執行成功失敗方法
Promise.prototype.then = function (onFulfilled,onRejected) {
let self = this;
onFulfilled = typeof onFulfilled == 'function'?onFulfilled:function(value){return value};
onReject = typeof onReject=='function'?onReject:function(reason){throw reason;}
if(self.status === 'resolved'){
return new Promise(function (resolve,reject) {
try {
let x = onFullFilled(self.value);
if(x instanceof Promise){
x.then(resolve,reject);
}else{
resolve(x);
}
}
catch(e) {
reject(e);
}
})
//執行成功方法
}else if(self.status == 'rejected'){
return new Promise(function (resolve,reject) {
try {
let x = onRejected(self.reason);
if(x instanceof Promise){
x.then(resolve,reject);
}else{
resolve(x);
}
}
catch(e) {
reject(e)
}
})
//執行失敗方法
}
if(self.status === 'pending'){
return new Promise(function (reslove,reject) {
self.onResolvedCallBacks.push(function () {
let x = onFullFilled(self.value);
if(x instanceof Promise){
x.then(resolve,reject);
}else{
resolve(x);
}
})
self.onRejectedCallbacks.push(function () {
let x = onRejected(self.reason);
if(x instanceof Promise){
x.then(resolve,reject);
}else{
resolve(x);
}
})
})
//將成功失敗方法儲存在陣列裡
}
}
複製程式碼
Promise.all
Promise.all = all;
function all(iterable) {
var self = this;
if (!isArray(iterable)) {
return this.reject(new TypeError('must be an array'));
}
var len = iterable.length;
var called = false;
if (!len) {
return this.resolve([]);
}
var values = new Array(len);
var resolved = 0;
var i = -1;
var promise = new this(INTERNAL);
while (++i < len) {
allResolver(iterable[i], i);
}
return promise;
function allResolver(value, i) {
self.resolve(value).then(resolveFromAll, function (error) {
if (!called) {
called = true;
doReject(promise, error);
}
});
function resolveFromAll(outValue) {
values[i] = outValue;
if (++resolved === len && !called) {
called = true;
doResolve(promise, values);
}
}
}
}
複製程式碼
Promise.then
Promise.race = function(iterable) {
var self = this;
if (!isArray(iterable)) {
return this.reject(new TypeError('must be an array'));
}
var len = iterable.length;
var called = false;
if (!len) {
return this.resolve([]);
}
var i = -1;
var promise = new this(INTERNAL);
while (++i < len) {
resolver(iterable[i]);
}
return promise;
function resolver(value) {
self.resolve(value).then(function (response) {
if (!called) {
called = true;
doResolve(promise, response);
}
}, function (error) {
if (!called) {
called = true;
doReject(promise, error);
}
});
}
}
複製程式碼