成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Promises與 async/await

beita / 2929人閱讀

摘要:是一種與協(xié)作的特殊的語(yǔ)法。換句話說(shuō),僅可以運(yùn)行在中。所以將會(huì)進(jìn)行等待,而之后拋出一個(gè)錯(cuò)誤。同時(shí)這也將更為便利。允許在函數(shù)內(nèi)部使用。關(guān)鍵詞確保運(yùn)行時(shí)將會(huì)等待處理完畢,并且如果觸發(fā)了一個(gè)運(yùn)行錯(cuò)誤,運(yùn)行中斷,并在改處類(lèi)似觸發(fā)。

“async/await”是一種與“promise”協(xié)作的特殊的語(yǔ)法。它使得異步工作更加容易理解和使用。

Async函數(shù)

我們從async關(guān)鍵詞開(kāi)始,它可以被放置在任何函數(shù)的開(kāi)頭位置,比如:

async function f() {
  return 1;
}

這里的async表示:該函數(shù)將始終返回一個(gè)promise。即使您的代碼沒(méi)有顯式返回一個(gè)promise,在JavaScript運(yùn)行時(shí)也會(huì)自動(dòng)包裝一個(gè)promise,用于返回指定的值。

在這個(gè)例子中,這段代碼將會(huì)返回一個(gè)result為1的promise

async function f() {
  return 1;
}

f().then(alert); // 1

當(dāng)然,我們也可以顯式的返回一個(gè)promise:

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1

async確保了函數(shù)會(huì)返回一個(gè)promise。挺簡(jiǎn)單的對(duì)吧?接下來(lái),是另一個(gè)關(guān)鍵詞await,僅僅能在async標(biāo)記的函數(shù)中生效。

Await

語(yǔ)法說(shuō)明:

//該段代碼僅僅能在 async 標(biāo)記的函數(shù)中生效
let value = await promise;

關(guān)鍵詞await確保JavaScript運(yùn)行時(shí)將會(huì)等待promise執(zhí)行完畢并返回結(jié)果。
下面是一段使用promise并在一秒后返回結(jié)果的例子:

async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000)
  });

  let result = await promise; // 等待至promise獲得結(jié)果 (*)

  alert(result); // "done!"
}

f();

該函數(shù)在運(yùn)行至await時(shí),執(zhí)行了“pauses”操作,直至promise執(zhí)行完畢后重新執(zhí)行接下來(lái)的代碼。所以該段代碼將在一秒后顯示“done!”。
讓我們強(qiáng)調(diào)一遍:await將順序使得JavaScript的運(yùn)行時(shí)等待promise執(zhí)行完畢,而后繼續(xù)運(yùn)行余下代碼。等待時(shí)的操作并不會(huì)消耗任何CPU資源,因?yàn)榇藭r(shí)的運(yùn)行時(shí)可以同時(shí)執(zhí)行其他操作:執(zhí)行其他的代碼,處理事件邏輯等。
這僅僅是一項(xiàng)相對(duì)promise.than更為優(yōu)雅的語(yǔ)法來(lái)獲取promise的運(yùn)行結(jié)果,更容易閱讀和編寫(xiě)代碼而已。

不能將await用于任何標(biāo)準(zhǔn)函數(shù)

如果您嘗試將await運(yùn)行在任何未標(biāo)記為async的函數(shù)中,都會(huì)產(chǎn)生一個(gè)語(yǔ)法錯(cuò)誤

function f() {
  let promise = Promise.resolve(1);
  let result = await promise; // Syntax error
}

我們?nèi)绻麤](méi)有使用async標(biāo)記函數(shù),那么我們就會(huì)得到這個(gè)語(yǔ)法錯(cuò)誤。換句話說(shuō),await僅可以運(yùn)行在async function中。

讓我們修改 Promises chaining 中的例子,使用async/await來(lái)重寫(xiě)這個(gè)例子。

我們需要將.then替換為await。

我們需要將函數(shù)修改為async function。

async function showAvatar() {

  // read our JSON
  let response = await fetch("/article/promise-chaining/user.json");
  let user = await response.json();

  // read github user
  let githubResponse = await fetch(`https://api.github.com/users/${user.name}`);
  let githubUser = await githubResponse.json();

  // show the avatar
  let img = document.createElement("img");
  img.src = githubUser.avatar_url;
  img.className = "promise-avatar-example";
  document.body.append(img);

  // wait 3 seconds
  await new Promise((resolve, reject) => setTimeout(resolve, 3000));

  img.remove();

  return githubUser;
}

showAvatar();

相當(dāng)容易閱讀和理解對(duì)吧。

await 并不能在頂層環(huán)境中生效

人們?cè)陂_(kāi)始使用await時(shí),總是容易忘記必須在async function內(nèi)部使用。比如以下代碼將會(huì)報(bào)錯(cuò):

// syntax error in top-level code
let response = await fetch("/article/promise-chaining/user.json");
let user = await response.json();

所以我們需要聲明一個(gè)async function來(lái)包裹該段代碼。

await 可以接受 thenables

類(lèi)似promise.thenawait準(zhǔn)許使用then方法。需要申明的是,這里指的是一個(gè)非promise對(duì)象,但它持有.then方法,那么就可以配合await使用。
比如以下例子,await接受new Thenable(1):

class Thenable {
  constructor(num) {
    this.num = num;
  }
  then(resolve, reject) {
    alert(resolve); // function() { native code }
    // resolve with this.num*2 after 1000ms
    setTimeout(() => resolve(this.num * 2), 1000); // (*)
  }
};

async function f() {
  // waits for 1 second, then result becomes 2
  let result = await new Thenable(1);
  alert(result);
}

f();

如果await與一個(gè)含有.then方法的非promise對(duì)象組合,同時(shí)其支持resolvereject兩個(gè)方法作為參數(shù)。那么await將會(huì)等待其中之一的函數(shù)被調(diào)用(注釋?zhuān)?)所在行)并在之后繼續(xù)運(yùn)行剩余代碼。

Async方法

類(lèi)函數(shù)亦可以被定義為異步函數(shù),僅需將async置于函數(shù)聲明前。
類(lèi)似于:

class Waiter {
  async wait() {
    return await Promise.resolve(1);
  }
}

new Waiter()
  .wait()
  .then(alert); // 1

這和之前的其他代碼端是一樣的作用:應(yīng)用await返回一個(gè)promise對(duì)象。

錯(cuò)誤處理

如果promise順利完成,那么await promise將返回一個(gè)值。但假如觸發(fā)了錯(cuò)誤,那么將在此行代碼中throw一個(gè)錯(cuò)誤。

以下代碼:

async function f() {
  await Promise.reject(new Error("Whoops!"));
}

等同于:

async function f() {
  throw new Error("Whoops!");
}

在真實(shí)的運(yùn)行環(huán)境中,可能需要消耗一些時(shí)間來(lái)觸發(fā)錯(cuò)誤。所以await將會(huì)進(jìn)行等待,而之后拋出一個(gè)錯(cuò)誤。我們可以通過(guò)try…catch來(lái)捕獲錯(cuò)誤,同樣的方法也適用于throw:

async function f() {

  try {
    let response = await fetch("http://no-such-url");
  } catch(err) {
    alert(err); // TypeError: failed to fetch
  }
}

f();

觸發(fā)了錯(cuò)誤之后,運(yùn)行代碼將跳轉(zhuǎn)至catch代碼塊。我們可以使用如下代碼:

async function f() {

  try {
    let response = await fetch("/no-user-here");
    let user = await response.json();
  } catch(err) {
    // catches errors both in fetch and response.json
    alert(err);
  }
}

f();

但如果我們沒(méi)有使用try…catch,那么將會(huì)在異步調(diào)用f()時(shí)觸發(fā)rejected。我們也可以添加.catch來(lái)處理錯(cuò)誤:

async function f() {
  let response = await fetch("http://no-such-url");
}

// f() becomes a rejected promise
f().catch(alert); // TypeError: failed to fetch // (*)

如果我們忘記添加.catch,我們將獲得一個(gè)未被捕獲的錯(cuò)誤。我們也可以使用一個(gè)全局事件捕獲方法來(lái)處理,參見(jiàn)Promise chaining。

async/await 和 promise.then/catch

當(dāng)我們使用async/await時(shí),我們僅僅需要.then,因?yàn)?em>await會(huì)接受正確結(jié)果。我們可以使用try…catch來(lái)取代.catch。同時(shí)這也將更為便利。
但處于頂層代碼邏輯時(shí),我們的邏輯代碼處在async function以外,我們并不能直接使用await,所以添加.then/catch代碼塊來(lái)獲取最終結(jié)果是更為普遍的做法。

async/await與Promise.all相互合作

當(dāng)我們需要等待多個(gè)promises時(shí),我們可以使用Promise.all之后使用await:

// wait for the array of results
let results = await Promise.all([
  fetch(url1),
  fetch(url2),
  ...
]);

假如觸發(fā)了一個(gè)錯(cuò)誤,它也會(huì)和其他promise一樣工作:從運(yùn)行失敗的Promise.all節(jié)點(diǎn)中斷,之后我們可以通過(guò)try…catch來(lái)捕獲錯(cuò)誤。

總結(jié)

async定以后的函數(shù)有兩層作用:

確保它總是返回一個(gè)promise。

允許在函數(shù)內(nèi)部使用await

await關(guān)鍵詞確保js運(yùn)行時(shí)將會(huì)等待promise處理完畢,并且:

如果觸發(fā)了一個(gè)運(yùn)行錯(cuò)誤,promise運(yùn)行中斷,并在改處類(lèi)似觸發(fā)throw error。

此外,它將返回一個(gè)結(jié)果,所以我們可以將其賦值給一個(gè)變量。

我們一起提供了一個(gè)偉大的框架來(lái)更為簡(jiǎn)便的完成異步操作。

有了async/await的幫組,我們可以大幅減少使用promise.then/catch,但我們依然不應(yīng)該忘記這些技術(shù)是基于promises,很可能我們會(huì)不得不繼續(xù)使用promise的方法。同時(shí),Promise.all相當(dāng)適合等待多個(gè)任務(wù)順序執(zhí)行的操作。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/90046.html

相關(guān)文章

  • 現(xiàn)代JS中的流程控制:詳解Callbacks 、PromisesAsync/Await

    摘要:控制臺(tái)將顯示回調(diào)地獄通常,回調(diào)只能由一個(gè)異步函數(shù)調(diào)用。更多資源使更友好規(guī)范使用異步函數(shù)簡(jiǎn)化異步編碼旅程異步編程是一項(xiàng)在中無(wú)法避免的挑戰(zhàn)。 JavaScript經(jīng)常聲稱(chēng)是_異步_。那是什么意思?它如何影響發(fā)展?近年來(lái)這種方法有何變化? 請(qǐng)思考以下代碼: result1 = doSomething1(); result2 = doSomething2(result1); 大多數(shù)語(yǔ)言都處理每...

    shadowbook 評(píng)論0 收藏0
  • 現(xiàn)代JS中的流程控制:詳解Callbacks 、Promises 、Async/Await

    摘要:控制臺(tái)將顯示回調(diào)地獄通常,回調(diào)只能由一個(gè)異步函數(shù)調(diào)用。更多資源使更友好規(guī)范使用異步函數(shù)簡(jiǎn)化異步編碼旅程異步編程是一項(xiàng)在中無(wú)法避免的挑戰(zhàn)。 JavaScript經(jīng)常聲稱(chēng)是_異步_。那是什么意思?它如何影響發(fā)展?近年來(lái)這種方法有何變化? 請(qǐng)思考以下代碼: result1 = doSomething1(); result2 = doSomething2(result1); 大多數(shù)語(yǔ)言都處理每...

    oujie 評(píng)論0 收藏0
  • 現(xiàn)代JS中的流程控制:詳解Callbacks 、Promises 、Async/Await

    摘要:控制臺(tái)將顯示回調(diào)地獄通常,回調(diào)只能由一個(gè)異步函數(shù)調(diào)用。更多資源使更友好規(guī)范使用異步函數(shù)簡(jiǎn)化異步編碼旅程異步編程是一項(xiàng)在中無(wú)法避免的挑戰(zhàn)。 JavaScript經(jīng)常聲稱(chēng)是_異步_。那是什么意思?它如何影響發(fā)展?近年來(lái)這種方法有何變化? 請(qǐng)思考以下代碼: result1 = doSomething1(); result2 = doSomething2(result1); 大多數(shù)語(yǔ)言都處理每...

    anquan 評(píng)論0 收藏0
  • async & await (譯)

    摘要:的出現(xiàn),讓我們可以走出回調(diào)地獄,著實(shí)驚艷。我已經(jīng)開(kāi)始使用里的和關(guān)鍵字來(lái)簡(jiǎn)化的處理。異步任務(wù)在這個(gè)例子是執(zhí)行之后,一直在執(zhí)行完成才繼續(xù)下一個(gè)任務(wù)并沒(méi)有產(chǎn)生阻塞。最后這個(gè)函數(shù)處理了返回值并且返回了一個(gè)對(duì)象。依然很棒,但和使得它可維護(hù)性更好。 JavaScript Promises的出現(xiàn),讓我們可以走出回調(diào)地獄,著實(shí)驚艷。Promises 允許我們更好的引入和處理異步任務(wù),雖然如此,但引入好...

    The question 評(píng)論0 收藏0
  • 翻譯:Taming the asynchronous beast with ES7

    摘要:讓我們使用它從數(shù)組中返回一個(gè)值數(shù)組在中,我們可以這樣做,這是一種更簡(jiǎn)單的方法最重要的部分是創(chuàng)建數(shù)組,該數(shù)組立即調(diào)用所有的我們?cè)谥骱瘮?shù)中等待這些。所以在我們真正等待完成之前,主函數(shù)就退出了。 原文:https://pouchdb.com/2015/03/0... PouchDB最棘手的方面之一是它的API是異步的。在Stack Overflow、Github和IRC上,我看到了不少困惑的...

    Eastboat 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<