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

資訊專欄INFORMATION COLUMN

JS中的async/await -- 異步隧道盡頭的亮光

jaysun / 1477人閱讀

摘要:結果輸出可以看出函數返回的是一個對象,如果函數中一個直接量,函數會封裝成對象返回,而如果沒有返回值時,函數會返回在沒有結合時,函數會立即執行,返回一個對象。

JS中的異步操作從最初的回調函數演進到Promise,再到Generator,都是逐步的改進,而async函數的出現仿佛看到了異步方案的終點,用同步的方式寫異步。

原文鏈接

async函數

簡單解釋async函數就是Generator函數的語法糖。

Generator函數寫法

let promise = function (val){
    return new Promise(function (resolve, reject){
        setTimeout(()=>{
            console.log(val);
            resolve(val);
        },1000);
    });
};

let gen = function* (){
    let p1 = yield promise("1");
    let p2 = yield promise("2");
};

let genF = gen();

async函數寫法

let promise = function (val){
    return new Promise(function (resolve, reject){
        setTimeout(()=>{
            console.log(val);
            resolve(val);
        },1000);
    });
};

let gen = async function (){
    let p1 = await promise("1");
    let p2 = await promise("2");
};

async函數是在Generator函數上進行的改進,語法上Generator函數的星號換成了async,yield換成了await。
而async也與Generator函數不同:

自帶內置執行器,Generator函數需要依靠執行器,而async可以和普通函數一樣,只需要一行

相對Generator函數,async和await語義更清楚

適用性強,yield后只能是Thunk函數和Promise對象,而await后可以是Promise對象和原始類型的值(數值、字符串、布爾型等)

async作用

寄予async函數的期望是希望可以幫助我們解決異步操作問題,所以需要搞清楚async函數的返回值是什么。

async function asyncAwait() {
    return "async await";
}

let a = asyncAwait();
console.log(a);

結果輸出:

Promise {: "async await"}

可以看出async函數返回的是一個Promise對象,如果函數中return一個直接量,async函數會封裝成Promise對象返回,而如果沒有返回值時,async函數會返回undefined

Promise {: undefined}

在沒有結合await時,async函數會立即執行,返回一個Promise對象。

await等待

await是個運算符,等待的結果是Promise對象或其他值,比如:

function func1() {
    return "async";
}

async function func2() {
    return Promise.resolve("await");
}

async function asyncAwait() {
    let f1 = await func1();
    let f2 = await func2();
    console.log(f1, f2);
}

asyncAwait()

結果輸出:

async await

await表達式的運算取決于等待的結果,如果它等到的不是一個Promise對象,那運算結果就是它等到的東西,
而如果它等到的是一個Promise對象,它會阻塞后面的代碼,等著Promise對象resolve,然后得到resolve的值,作為表達式的運算結果。
async函數調用會封裝在Promise中,這也是await需要在async函數中使用的原因。

async/await鏈式處理

對于多個異步操作中,Promise的then可以解決多層回調問題。

function ajax(t) {
    return new Promise(resolve => {
        setTimeout(() => resolve(t + 200), t);
    });
}

function step1(t) {
    console.log(`step1 in ${t}ms`);
    return ajax(t);
}

function step2(t) {
    console.log(`step2 in ${t}ms`);
    return ajax(t);
}

function step3(t) {
    console.log(`step3 in ${t}ms`);
    return ajax(t);
}

function submit(){
    console.time("submit");
    step1(200)
        .then(time2 => step2(time2))
        .then(time3 => step3(time3))
        .then(result => {
            console.log(`result is ${result}ms`);
            console.timeEnd("submit");
        });
}

submit();

async函數實現:

function ajax(t) {
    return new Promise(resolve => {
        setTimeout(() => resolve(t + 200), t);
    });
}

function step1(t) {
    console.log(`step1 in ${t}ms`);
    return ajax(t);
}

function step2(t) {
    console.log(`step2 in ${t}ms`);
    return ajax(t);
}

function step3(t) {
    console.log(`step3 in ${t}ms`);
    return ajax(t);
}

async function submit(){
    console.time("submit");
    const t1 = 200;
    const t2 = await step1(t1);
    const t3 = await step2(t2);
    const result = await step3(t3);
    console.log(`result is ${result}`);
    console.timeEnd("submit");
}

submit();

結果輸出:

step1 in 200ms
step2 in 400ms
step3 in 600ms
result is 800
submit: 1209.85107421875ms

而如果需求變更,每一步的參數都是之前步驟的結果后,async函數可以寫成:

function ajax(t) {
    return new Promise(resolve => {
        setTimeout(() => resolve(t + 200), t);
    });
}

function step1(t1) {
    console.log(`step1 in ${t1}ms`);
    return ajax(t1);
}

function step2(t1, t2) {
    console.log(`step2 in ${t1}ms,${t2}ms`);
    return ajax(t1 + t2);
}

function step3(t1, t2, t3) {
    console.log(`step3 in ${t1}ms,${t2}ms,${t3}ms`);
    return ajax(t1 + t2 + t3);
}

async function submit(){
    console.time("submit");
    const t1 = 200;
    const t2 = await step1(t1);
    const t3 = await step2(t1, t2);
    const result = await step3(t1, t2, t3);
    console.log(`result is ${result}`);
    console.timeEnd("submit");
}

submit();

結果輸出:

step1 in 200ms
step2 in 200ms,400ms
step3 in 200ms,400ms,800ms
result is 1600
submit: 2210.47998046875ms
async/await注意點

async用來申明里面包裹的內容可以進行同步的方式執行,await則是進行執行順序控制,每次執行一個await,阻塞代碼執行等待await返回值,然后再執行之后的await。

await后面調用的函數需要返回一個promise。

await只能用在async函數之中,用在普通函數中會報錯。

await命令后面的Promise對象,運行結果可能是rejected,所以最好把await命令放在try...catch代碼塊中。

async/await try/catch寫法
async function asyncAwait() {
    try {
        await promise();
    } catch (err) {
        console.log(err);
    }
}

// 另一種寫法
async function asyncAwait() {
    await promise().catch(function (err){
        console.log(err);
    });
}
總結

async/await是ES7的重要特性之一,也是目前社區里公認的優秀異步解決方案,當你深入了解原理后會發現仿佛看到了異步回調隧道的盡頭亮光。

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

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

相關文章

  • ES6 Async/Await 完爆Promise6個原因

    摘要:以往的異步方法無外乎回調函數和。當然,對這個新特性也有一定的擔心,體現在他使得異步代碼變的不再明顯,我們好不容易已經學會并習慣了使用回調函數或者來處理異步。 自從Node的7.6版本,已經默認支持async/await特性了。如果你還沒有使用過他,或者對他的用法不太了解,這篇文章會告訴你為什么這個特性不容錯過。本文輔以大量實例,相信你能很輕松的看懂,并了解Javascript處理異步的...

    shevy 評論0 收藏0
  • ES6 Async/Await 完爆Promise6個原因

    摘要:以往的異步方法無外乎回調函數和。當然,對這個新特性也有一定的擔心,體現在他使得異步代碼變的不再明顯,我們好不容易已經學會并習慣了使用回調函數或者來處理異步。 自從Node的7.6版本,已經默認支持async/await特性了。如果你還沒有使用過他,或者對他的用法不太了解,這篇文章會告訴你為什么這個特性不容錯過。本文輔以大量實例,相信你能很輕松的看懂,并了解Javascript處理異步的...

    W4n9Hu1 評論0 收藏0
  • Generator和Async/Await

    摘要:以往的異步方法無外乎回調函數和。出錯了出錯了總結接口遍歷器對象除了具有方法,還可以具有方法和方法。函數調用函數,返回一個遍歷器對象,代表函數的內部指針。 引言 接觸過Ajax請求的會遇到過異步調用的問題,為了保證調用順序的正確性,一般我們會在回調函數中調用,也有用到一些新的解決方案如Promise相關的技術。 在異步編程中,還有一種常用的解決方案,它就是Generator生成器函數。顧...

    Eastboat 評論0 收藏0
  • 淺析JavaScript異步

    摘要:回調函數,一般在同步情境下是最后執行的,而在異步情境下有可能不執行,因為事件沒有被觸發或者條件不滿足。同步方式請求異步同步請求當請求開始發送時,瀏覽器事件線程通知主線程,讓線程發送數據請求,主線程收到 一直以來都知道JavaScript是一門單線程語言,在筆試過程中不斷的遇到一些輸出結果的問題,考量的是對異步編程掌握情況。一般被問到異步的時候腦子里第一反應就是Ajax,setTimse...

    Tangpj 評論0 收藏0

發表評論

0條評論

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