国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

async/await 和 Promise 的用例&關系

y1chuan / 794人閱讀

摘要:和的關系和的關系非常的巧妙,必須在內使用,并裝飾一個對象,返回的也是一個對象。的會使得的代碼節點自動拋出相應的異常,終止向下繼續執行。示例方法內無節點沒有修飾的方法內有節點注意內的對節點的作用。

假設我們有三個請求,req1,req2, req3,三個請求后者依賴前者的請求結果。我們先使用Promise封裝一個異步請求的方法。

Promise 異步請求

使用Promise可以非常容易的封裝一個異步處理的業務,通過reslove/reject兩個callback來返回執行結果。

我們使用 Promise 封裝一個 http get方法。

// 返回一個 Promise 對象(PromiseStatus: pending)
function asyncHttpGet(url) {
    return new Promise((resolve, reject) => {
        const request = new Request(url, {method: "GET"})
        // 使用 fetch 請求
        fetch(request)
            .then(response => {
                if (200 == response.status) {
                    return response.text()
                } else {
                    // goto catch
                    throw new Error("request failed: " + response.status)
                }
            }).then(html => {
                // console.log(html)
                resolve(url + " get success")
            }).catch(err => {
                reject(err)
            });
    })
}

fetch返回的其實就是一個Promise對象,上例是想演示下resolve/reject的使用上下文,如果你早已get,下面給出直接使用fetch的方式:

async function asyncHttpGetV2(url) {
    const request = new Request(url, {method: "GET"})
    try {
        let res = await fetch(request)
            .then(response => response.blob())
            .then(blob => {
                console.log(blob)
                // Promise resolve
                return blob
            }).catch(err => {
                // Promise resolve
                throw err
            });
        // Promise resolve
        return res;
    } catch (err) {
        // Promise reject
        throw err
    }
}

可以發現,fetchreturn 代替了resolvethrow代替了reject,而asyncfetch一樣,也是返回了一個 Promise對象,所以async中的return/throw是否也會與自己的返回的Promise對象有關系呢?

回調地獄

Promise 可以優雅的實現異步,但 Promise.then().catch() 的鏈式結構也帶來了回調地獄的問題。如下,我們回調了3層,才能開始寫業務邏輯。

var url = window.location.href
// 雖然異步了 但 callback hell
asyncHttpGet(url).then(res => {
    var res1 = res
    asyncHttpGet(url).then(res => {
        var res2 = res
        asyncHttpGet(url).then(res => {
            var res3 = res
            console.log(res1, res2, res3);
            // todo 業務
        }).catch(err => {
            console.log(err)
        })        
    }).catch(err => {
        console.log(err)
    })
}).catch(err => {
    console.log(err)
})
async/await

借助 aysnc/await 解決回調地獄的問題,實現同步風格的異步邏輯,這里希望大家能理解透2 & 3兩條總結:

aysnc 返回的也是一個 Promise 對象。

如果返回了return 標量throw Error 則返回 {PromiseStatus: resolved/rejected}Promise對象。

如果遇到了await裝飾的Promise,則返回 {PromiseStatus: pending}Promise。并等待此Promise的執行結果:如果Promise觸發了resolve則獲取結果并繼續向下執行;如果Promise觸發了reject則拋出一個異常。所以我們在使用時應將代碼使用try...catch封裝。

await 關鍵字只能在 async內使用,await主要意圖是裝飾一個以 {PromiseStatus: pending}的狀態返回的Promise對象(任何 JS 表達式都可以,但沒什么意義),并等待其后續的resolved/rejected狀態更新,從而決定是獲得結果并繼續向下執行,還是終止并拋出異常。

var url = window.location.href

async function getUrls(url1, url2, url3) {
    try {
        // req1 success or throw error (promise reject)
        let res1 = await asyncHttpGet(url1);
        
        // req2 success or throw error (promise reject)
        let res2 = await asyncHttpGet(url2);
        
        // req3 success or throw error (promise reject)
        let res3 = await asyncHttpGet(url3);
        
        // 三個異步請求都成功 獲取最終結果
        return [res1, res2, res3].join("
")
    } catch(err) {
        // 出現錯誤,做一些處理
        console.log(err)
        throw err
    }
}

// 如此 3 個 Promise 請求在 async/await 的封裝下變成了一個同步書寫風格的異步請求
getUrls(url, url, url).then(res => {
    console.log(res)
    // todo 業務
}).catch(err => {
    console.log(err)
})

console.log("request has been sended, and waiting for res")

async 返回的是 Promise對象,所以我們還可以繼續使用 asyncawait封裝異步到同步風格。

async function getUrlsMore(url1, url2) {
    try {
        let getUrls1 = await getUrls(url1, url1, url1)
        let getUrls2 = await getUrls(url2, url2, url2)
        
        // Promise resolve
        return [getUrls1, getUrls2].join("
")
    } catch (err) {
        // Promise reject
        throw err
    }
}

getUrlsMore(url, url).then(res => {
    console.log(res)
}).catch(err => {
    console.log(err)
})
async/await 和 Promise 的關系

async/awaitPromise 的關系非常的巧妙,await必須在async內使用,并裝飾一個Promise對象,async返回的也是一個Promise對象。

async/await中的return/throw會代理自己返回的Promiseresolve/reject,而一個Promiseresolve/reject會使得await得到返回值或拋出異常。

如果方法內無await節點

return 一個字面量則會得到一個{PromiseStatus: resolved}Promise
throw 一個Error則會得到一個{PromiseStatus: rejected}Promise

如果方法內有await節點
async會返回一個{PromiseStatus: pending}Promise(發生切換,異步等待Promise的執行結果)。
Promiseresolve會使得await的代碼節點獲得相應的返回結果,并繼續向下執行。
Promisereject 會使得await的代碼節點自動拋出相應的異常,終止向下繼續執行。

示例:

方法內無await節點
// 沒有 await 修飾的 Promise
async function foo() {
    if (Math.ceil(Math.random() * 10) > 5) {
        // {PromiseStatus: resolved}
        return "hello world"
    } else {
        // {PromiseStatus: rejected}
        throw new Error("something wrong!")
    }
}

var fooPromise = foo()
console.log(fooPromise)

fooPromise.then(res => {
    console.log(res)
}).catch(err => {
    console.log(err)
})

resolved

rejected

方法內有await節點

注意Promise內的resolve/rejectawait節點的作用。

async function bar() {
    try {
        // await 返回 {PromiseStatus: pending}
        let res = await new Promise((resolve, reject) => {
            setTimeout(() => {
                if (Math.ceil(Math.random() * 10) > 5) {
                    // await 獲得結果并繼續執行
                    resolve("success")
                } else {
                    // await 中斷執行并拋出異常
                    reject("failed")
                }
            }, 2000)
        })
        // resolve {PromiseStatus: resolved}
        return res
    } catch (err) {
        // reject {PromiseStatus: rejected}
        throw err
    }
}

var barPromise = bar()

// 查看 barPromise 的 PromiseStatus
console.log(barPromise)

barPromise.then(res => {
    console.log(res)
}).catch(err => {
    console.log(err)
})
await配合fetch的實例

then/catch返回的也是Promise對象,在then/catch內使用return/throw來決定返回的Promiseresolved/rejected

// 沒有 await 修飾的 Promise
async function bar() {
    try {
        // await 返回 {PromiseStatus: pending}
        let res1 = await fetch(window.location.href).then(res => {
            if (200 == res.status) {
                // Promise resolve
                return "request success"
            } else {
                // goto catch
                throw "request failed" + res.status
            }
        }).catch(err => {
            // Promise reject
            throw err
        })
        
        let res2 = await fetch(window.location.href).then(res => {
            if (200 == res.status) {
                // Promise resolve
                return "request success"
            } else {
                // goto catch
                throw "request failed" + res.status
            }
        }).catch(err => {
            // Promise reject
            throw err
        })
        
        let res3 = await fetch(window.location.href).then(res => {
            if (200 == res.status) {
                // Promise resolve
                return "request success"
            } else {
                // goto catch
                throw "request failed" + res.status
            }
        }).catch(err => {
            // Promise reject
            throw err
        })
        
        // 三個請求都成功 則返回相應的數據 Promise resolved
        return [res1, res2, res3].join("
")
    } catch (err) {
        // Promise rejected
        throw err
    }
}

var barPromise = bar()

// 查看 barPromise 的 PromiseStatus
console.log(barPromise)

// Promise reject 拋出異常 需要使用 catch 捕捉
barPromise.then(res => {
    console.log(res)
}).catch(err => {
    console.log(err)
})

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/110298.html

相關文章

  • Promise && async/await的理解用法

    摘要:但是中的這種情況與抽象反應器模式如何描述完全不同。在處理一個階段之后并且在移到下一個隊列之前,事件循環將處理兩個中間隊列,直到中間隊列中沒有剩余的項目。如果沒有任務則循環退出,每一次隊列處理都被視為事件循環的一個階段。 Promise && async/await的理解和用法 為什么需要promise(承諾)這個東西 在之前我們處理異步函數都是用回調這個方法,回調嵌套的時候會發現 閱讀...

    王笑朝 評論0 收藏0
  • async & await & promise

    摘要:最近項目中用的比較多,所以特地去了解,模仿一下實現先來看看使用的方法通過是通過使用生成器配合方法模擬的一個同步操作,這個技術有效的避免了傳統回調和形成的回調地獄。 最近項目中 asyn & await 用的比較多,所以特地去了解,模仿一下實現~ 先來看看 使用 async & await 的方法 async function d () { try { const a = a...

    Dean 評論0 收藏0
  • async & await (譯)

    摘要:的出現,讓我們可以走出回調地獄,著實驚艷。我已經開始使用里的和關鍵字來簡化的處理。異步任務在這個例子是執行之后,一直在執行完成才繼續下一個任務并沒有產生阻塞。最后這個函數處理了返回值并且返回了一個對象。依然很棒,但和使得它可維護性更好。 JavaScript Promises的出現,讓我們可以走出回調地獄,著實驚艷。Promises 允許我們更好的引入和處理異步任務,雖然如此,但引入好...

    The question 評論0 收藏0
  • setTimeout&Promise&Async之間的愛恨情仇

    摘要:但是提出標準,允許腳本創建多個線程,但是子線程完全受主線程控制。只是將事件插入了任務隊列,必須等到當前代碼執行棧執行完,主線程才會去執行它指定的回調函數。之后全局上下文進入函數調用棧。 setTimeout 一、setTimeout 初現 定義:setTimeout() 方法用于在指定的毫秒數后調用函數或計算表達式。 語法: setTimeout(code, millisec...

    Half 評論0 收藏0
  • js異步從入門到放棄(實踐篇) — 常見寫法&面試題解析

    摘要:前文該系列下的前幾篇文章分別對不同的幾種異步方案原理進行解析,本文將介紹一些實際場景和一些常見的面試題。流程調度里比較常見的一種錯誤是看似串行的寫法,可以感受一下這個例子判斷以下幾種寫法的輸出結果辨別輸出順序這類題目一般出現在面試題里。 前文 該系列下的前幾篇文章分別對不同的幾種異步方案原理進行解析,本文將介紹一些實際場景和一些常見的面試題。(積累不太夠,后面想到再補) 正文 流程調度...

    Awbeci 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<