JavaScript——promise 是解決非同步問題的方法嘛
阿新 • • 發佈:2020-10-13
前言
- promise
- 非同步解決方案
步驟
Promise 物件是 JavaScript 的非同步操作解決方案,為非同步操作提供統一介面。它起到代理作用(proxy),充當非同步操作與回撥函式之間的中介,使得非同步操作具備同步操作的介面。Promise 可以讓非同步操作寫起來,就像在寫同步操作的流程,而不必一層層地巢狀回撥函式。
Promise解決了callback回撥地獄的問題,async、await 是非同步的終極解決方案。
來看一下JavaScript中非同步方案
1)回撥函式(callback)
setTimeout(() => { // callback 函式體 }, 1000)
缺點: 回撥地獄,不能用 try catch 捕獲錯誤,不能 return
回撥地獄的根本問題在於:
- 缺乏順序性: 回撥地獄導致的除錯困難,和大腦的思維方式不符
- 巢狀函式存在耦合性,一旦有所改動,就會牽一髮而動全身,即(控制反轉)
- 巢狀函式過多的多話,很難處理錯誤
ajax('XXX1', () => { // callback 函式體 ajax('XXX2', () => { // callback 函式體 ajax('XXX3', () => { // callback 函式體 }) }) })
優點: 解決了同步的問題(只要有一個任務耗時很長,後面的任務都必須排隊等著,會拖延整個程式的執行。)
2)Promise
Promise就是為了解決callback的問題而產生的。Promise 實現了鏈式呼叫,也就是說每次 then 後返回的都是一個全新 Promise,如果我們在 then 中 return ,return 的結果會被 Promise.resolve() 包裝
優點: 解決了回撥地獄的問題
ajax('XXX1') .then(res => { // 操作邏輯 return ajax('XXX2') }).then(res => { // 操作邏輯 return ajax('XXX3') }).then(res => { // 操作邏輯 })
缺點: 無法取消 Promise ,錯誤需要通過回撥函式來捕獲
3)Generator
特點: 可以控制函式的執行,可以配合 co 函式庫使用
function *fetch() {
yield ajax('XXX1', () => {})
yield ajax('XXX2', () => {})
yield ajax('XXX3', () => {})
}
let it = fetch()
let result1 = it.next()
let result2 = it.next()
let result3 = it.next()
4)Async/await
async、await 是非同步的終極解決方案
優點: 程式碼清晰,不用像 Promise 寫一大堆 then 鏈,處理了回撥地獄的問題
缺點: await 將非同步程式碼改造成同步程式碼,如果多個非同步操作沒有依賴性而使用 await 會導致效能上的降低。
async function test() {
// 以下程式碼沒有依賴性的話,完全可以使用 Promise.all 的方式
// 如果有依賴性的話,其實就是解決回撥地獄的例子了
await fetch('XXX1')
await fetch('XXX2')
await fetch('XXX3')
}