要理解非同步,首先,從同步**開始說
alert(1)
alert(2)
像上面的**,執行順序是從上到下,先後彈出1和2,這種**叫做同步**
alert(0)
settimeout(function () , 2000);
settimeout(function () , 1000);
alert(3)
上面**的彈出順序是 0 3 2 1 ,像這種不按從上到下依次執行的**叫做非同步**,其實還有很多類似的非同步**,例如:ajax請求
ajax(
})console.log(111)
非同步**巢狀問題
settimeout(function () , 10)
}, 100)
}, 1000)
promise是es6中的非同步程式設計解決方案,在**中表現為乙個物件,可以通過建構函式promise來例項化,有了promise物件,可以將非同步操作以同步的流程表達出來,避免了**地獄(**函式層層巢狀)
直觀的去看看promise到底是什麼
console.dir(promise)
這樣一看就很明白了,promise是乙個建構函式,它身上有幾個方法,例如:reject、resolve、catch、all、race等方法就是我們常用的一些方法,還有then方法在它的原型上,也是非常常用的,後面我們會詳細講解這些方法
既然是建構函式,那麼我們就可以使用new來呼叫一下,簡單的使用
let p = new promise((resolve, reject) => , 1000)
})
promise物件代表乙個非同步操作,有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗),上面**中傳入的函式有兩個引數,resolve和reject,這兩個引數都是函式塊,用於**執行,resolve是將promise的狀態置為fullfiled,reject是將promise的狀態置為rejected,只有這兩個結果可以去操作promise的狀態,其他任何操作都不能更改這個狀態,這也是promise這個名字的由來,它的英語意思就是「承諾」,表示其他手段無法改變。在初學階段你可以簡單的理解為resole就是非同步執行成功後被呼叫的函式,reject是非同步執行失敗後呼叫的函式
注意: 上面**中我們只是去new promise() 得到乙個例項,但是發現非同步**中的語句在1秒後被執行了,也就是說只要new promise(), 那麼promise裡面的函式就會被立即執行,這是非常重要的乙個細節,我們應該做到需要的時候去執行,而不是不管什麼情況都去執行,因此,我們通常把上面的**包到乙個函式中去,需要的時候,呼叫一下函式就可以了
function asyncfn() , 1000)
});return p;
}
函式封裝好後到底有什麼用?在什麼情況下用?resolve拿來做什麼? 帶著這些疑問,我們繼續往下講
在promise的原型上有乙個叫做then的方法,它的作用是為 promise 例項新增狀態改變時的**函式,我們首先來看看then方法的位置
console.dir(promise)
下面我們來具體使用這個then方法
function asyncfn() , 1000)
});return p;
}asyncfn().then(function () )
**寫到這裡,我們已經能看出promise的作用了,它其實已經可以把原來**函式函式寫到非同步**裡的這種寫法改變了,它已經把**函式函式分離出來了,在非同步**執行完成後,通過鏈式呼叫的方式來執行**函式函式,如果僅僅是向上面的**只執行一次**函式可能看不出promise帶來的好處,下面我們來看更複雜的**
function asyncfn1() , 1000)
});return p;
}function asyncfn2() , 3000)
});return p;
}function asyncfn3() , 2000)
});return p;
}
需求:asyncfn3 是依賴於asyncfn2的 asyncfn2是依賴於asyncfn1的,這就要求asyncfn1執行完成後再執行asyncfn2,asyncfn2執行完成後執行asyncfn3,這個時候怎麼寫?
function asyncfn1() , 1000)
});return p;
}function asyncfn2() , 3000)
});return p;
}function asyncfn3() , 2000)
});return p;
}//需求:asyncfn3 是依賴於asyncfn2的 asyncfn2是依賴於asyncfn1的,這就要求asyncfn1執行完成後
// 再執行asyncfn2,asyncfn2執行完成後執行asyncfn3,這個時候怎麼寫?
asyncfn1().then(()=>).then(()=>).then(()=>)
到底為止,promise的作用已經差不多可以理解了,它是es6中的非同步解決方案,可以將非同步的**以同步的形式表現出來,避免**函式函式巢狀
如果理解了resolve的話,那麼理解reject就比較容易了,它是非同步**執行失敗後執行的**函式。reject的作用就是把promise的狀態置為rejected,這樣我們在then中就能捕捉到,然後執行「失敗」情況的**
let obtn = document.getelementbyid('btn');
let oresult = document.getelementbyid('result');
obtn.onclick = () => , () => )
};function asyncgetdata() else
})})
}
1.非同步載入
獲取
1.catch的用法
catch方法和then的第二個引數作用差不多,都是用來指定非同步執行失敗後的**函式函式的,不過,它還有乙個功能就是如果在resolve中丟擲錯誤,不會阻塞執行,而是可以在catch中捕獲到錯誤
模擬獲取資料
2.all方法
all方法中傳入乙個陣列,裡面是多個promise例項,只有當所有的promise例項的狀態變為fulfilled的時候,整體的狀態才會變成fulfilled,這個時候每個promise的例項返回的值會組成乙個陣列傳給**函式,如果整個陣列中的promise例項中有乙個的狀態是rejected,那麼整體的狀態都會是rejected,這個時候,第乙個rejected例項的返回值會傳給**函式
獲取
3.race方法
promise.race方法同樣是將多個 promise 例項,包裝成乙個新的 promise 例項。
const p = promise.race([p1, p2, p3]);
上面**中,只要p1、p2、p3之中有乙個例項率先改變狀態,p的狀態就跟著改變。那個率先改變的 promise 例項的返回值,就傳遞給p的**函式。
獲取
es6 最佳入門實踐 6
symbol是es6中一種新增加的資料型別,它表示獨一無二的值。es5中我們把資料型別分為基本資料型別 字串 數字 布林 undefined null 和引用資料型別 object 在es6中新增的symbol資料型別劃分到基本資料型別 為什麼會有這樣一種資料型別呢?別人給了你乙個定義好的物件 va...
es6 最佳入門實踐 12
在es5中,物件導向我們通常寫成這樣 function person name,age person.prototype.showname function let p new person xiaoqiang 10 p.showname 上面這種寫法與傳統的物件導向寫法有很大的不同,讓學習過其他物...
es6 最佳入門實踐 10
generator函式是es6提供的一種非同步程式設計解決方案。在它的內部封裝了多個狀態,因此,又可以理解為一種狀態機,執行generator函式後返回乙個迭代器物件,使用這個迭代器物件可以遍歷出generator函式內部的狀態 generator函式和傳統函式的不同點有 1 函式定義的時候,fun...