首頁  >  文章  >  web前端  >  JS中的async/await

JS中的async/await

php中世界最好的语言
php中世界最好的语言原創
2018-03-13 15:57:452288瀏覽

這次帶給大家JS中的async/await,使用JS中的async/await的注意事項有哪些,下面就是實戰案例,一起來看一下。

JS中的非同步操作從最初的回呼函數演進到Promise,再到Generator,都是逐步的改進,而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 {<resolved>: "async await"}

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

Promise {<resolved>: undefined}

在沒有結合await時,async函數會立即執行,傳回一個Promise物件。

await等待

await是個運算子,等待的結果是Promise物件或其他值,例如:

function func1() {    return &#39;async&#39;;
}async function func2() {    return Promise.resolve(&#39;await&#39;);
}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(&#39;submit&#39;);
    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(&#39;submit&#39;);    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(&#39;submit&#39;);
}
submit();

結果輸出:

step1 in 200ms
step2 in 400ms
step3 in 600ms
result is 800submit: 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(&#39;submit&#39;);    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(&#39;submit&#39;);
}
submit();

結果輸出:

step1 in 200ms
step2 in 200ms,400ms
step3 in 200ms,400ms,800ms
result is 1600submit: 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);
    });
}

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

React.js的Mixins.js使用詳解

React.js中的CSS使用

以上是JS中的async/await的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn