|
導讀網頁的本質就是超級文本標記語言,通過結合使用其他的Web技術(如:腳本語言、公共網關接口、組件等),可以創造出功能強大的網頁。因而,超級文本標記語言是萬維網(Web)編程的基礎,也就是說萬維網是建立... 網頁的本質就是超級文本標記語言,通過結合使用其他的Web技術(如:腳本語言、公共網關接口、組件等),可以創造出功能強大的網頁。因而,超級文本標記語言是萬維網(Web)編程的基礎,也就是說萬維網是建立在超文本基礎之上的。超級文本標記語言之所以稱為超文本標記語言,是因為文本中包含了所謂“超級鏈接”點。 本篇文章給大家帶來的內容是關于promise對象的深入解析(附示例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。js中的異步,剛開始的時候都是用回調函數實現的,所以如果異步嵌套的話,就有出現回調地獄,使得代碼難以閱讀和難以維護,后來es6出現了promise,解決了回調地獄的問題。現在我們就自己寫代碼實現一下promise,這樣才能深入理解promise的運行機制,對以后使用promise也能夠更加得心應手。開始之前可以先看下promise的官網promise/A+ 先來看下promise的用法 new Promise((resolve,reject)=>{
resolve(1);
reject(11);
}).then(res=>{
console.log(res);
setTimeout(()=>{
return new Promise((resolve,reject)=>{
resolve(2)
})
},1000)
}).then(res2=>{
console.log(res2);
});控制臺打印 先分析下上面這段代碼,先提出幾個問題 狀態機promise中有個狀態機的概念,先說下為什么要有狀態機的概念呢,因為promise的狀態是單向變化的,有三種狀態,pending,fullfilled,rejected,而這三種狀態只能從pending->fullfilled或者pending->rejected這兩種形式,也就是說執行了fullfilled之后,就不會執行rejected。這就解釋了上面的第一個問題。 下面我們來看下具體實現的完整代碼 const PENDING = 'PENDING';
const FULLFILLED = 'FULLFILLED';
const REJECTED = 'REJECTED';
class Promise{
constructor(fn){
this.status = PENDING;//狀態
this.data = undefined;//返回值
this.defercb = [];//回調函數數組
//執行promise的參數函數,并把resolve和reject的this綁定到promise的this
fn(this.resolve.bind(this),this.reject.bind(this));
}
resolve(value){
if(this.status === PENDING){
//只能pending=>fullfied
this.status = FULLFILLED;
this.data = value;
this.defercb.map(item=>item.onFullFilled());
}
}
reject(value){
if(this.status === PENDING){
//只能pending=>rejected
this.status = REJECTED;
this.data = value;
this.defercb.map(item=>item.onRejected());
}
}
then(resolveThen,rejectThen){
//如果沒有resolveThen方法,保證值可以穿透到下一個then里有resolveThen的方法中
resolveThen = typeof resolveThen === 'function' ? resolveThen : function(v) {return v};
rejectThen = typeof rejectThen === 'function' ? rejectThen : function(r) {return r};
//返回的都是promise對象,這樣就可以保證鏈式調用了
switch(this.status){
case PENDING:
return new Promise((resolve,reject)=>{
const onFullFilled = () => {
const result = resolveThen(this.data);//這里調用外部then的resolveThen方法,將值傳回去
//如果返回值是promise對象,執行then方法,取它的結果作為新的promise實例的結果,因為this.data會重新賦值
result instanceof Promise && result.then(resolve,reject);
}
const onRejected = ()=>{
const result = rejectThen(this.data);
result instanceof Promise && result.then(resolve,reject);
}
this.defercb.push({onFullFilled,onRejected});
});
break;
case FULLFILLED:
return new Promise((resolve,reject)=>{
const result = resolveThen(this.data);
result instanceof Promise && result.then(resolve,reject);
resolve(result);
})
break;
case REJECTED:
return new Promise((resolve,reject)=>{
const result = rejectThen(this.data);
result instanceof Promise && result.then(resolve,reject);
reject(result)
})
break;
}
}
}運行下面的例子 new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
}).then((res2) => {
console.log(res2);
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2);
}, 1000);
});
}).then((res3) => {
console.log(res3);
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(3);
}, 1000);
});
}).then((res4) => {
console.log(res4);
});控制臺打印 new Promise((resolve) => {
resolve();
})
.then(() => {
console.log('1');
})
.then(() => {
console.log('2');
});
console.log('3');并沒有像預想中輸出3,1,2,而是輸出了1,2,3,原因就是因為我們的這個Promise是在主線程中,沒有在下一個任務隊列中,可以加上settimeout解決這個問題,不過這也只是為了讓我們更好理解執行順序而已,然而實際上是promise是屬于微任務中的,而settimeout是屬于宏任務,還是不太一樣的 以上就是promise對象的深入解析(附示例)的詳細內容,更多請關注php中文網其它相關文章! 網站建設是一個廣義的術語,涵蓋了許多不同的技能和學科中所使用的生產和維護的網站。 |
溫馨提示:喜歡本站的話,請收藏一下本站!