同步等待 异步等待_异步等待

同步等待 异步等待

JavaScript promises were a revelation in JavaScript, providing an alternative to the JavaScript callback hell we'd quickly found ourselves in.  Promises also allowed us to introduce and better handle asynchronous tasks.  While promises were an improvement over callback hell, they still require lots of thens which can become messy.  I've really taken to ES2017's async and await keywords for simplifying promise handling.  Let's have a look at async and await!

JavaScript的承诺JavaScript的一个启示,它为我们很快发现JavaScript回调地狱提供了一种替代方法。Promise还允许我们引入并更好地处理异步任务。 虽然promise是对回调地狱的一种改进,但它们仍然需要大量的then ,这可能会变得凌乱。 我确实采用了ES2017的asyncawait关键字来简化承诺处理。 让我们看一下asyncawait

快速基础 (Quick Basics)

  • async is a keyword for the function declaration

    async是函数声明的关键字

  • await is used during the promise handling

    在承诺处理期间使用await

  • await must be used within an async function, though Chrome now supports "top level" await

    await必须在内部使用async功能,但Chrome浏览器现在支持“顶级” await

  • async functions return a promise, regardless of what the return value is within the function

    async函数返回一个promise,无论该函数中的return值是多少

  • async/await and promises are essentially the same under the hood

    async / await和承诺实际上是相同的

  • Available now in most browsers as well as Node.js

    现在大多数浏览器以及Node.js中都可用

asyncawait好处 (Benefits of async and await)

  • Your code is more simplistic, precise

    您的代码更加简单,精确
  • Debugging is easier thanks to less callbacks

    由于更少的回调,调试更容易
  • Conversion from promise then / catch code is easy

    从承诺转换then / catch代码很容易

  • Your code can be more "top down", less nesting

    您的代码可以更“自上而下”,更少的嵌套

基本asyncawait插图 (Basic async and await Illustration)

It's always easiest to learn from an example, so let's have a look at a very simple async / await usage:

从示例中学习总是最容易的,所以让我们看一个非常简单的async / await用法:

// Function declared as async so await can be used
async function fetchContent() {
  // Instead of using fetch().then, use await
  let content = await fetch('/');
  let text = await content.text();
  
  // Inside the async function text is the request body
  console.log(text);

  // Resolve this async function with the text
  return text;
}

// Use the async function
var promise = fetchContent().then(...);

Start by declaring the function as async; this declaration allows await to be used from within.  The await keyword is then followed by a promise-yielding action, which of course the fetch API is.  The asynchronous routine (fetch in this case) runs and execution of further code halts (though not blocking) until the async action finishes.  The function then resolves with the return value and a promise is returned.

首先将函数声明为async ; 此声明允许await从内使用。 然后, await关键字之后执行一个承诺承诺操作,这当然是fetch API 。 异步例程(在这种情况下为fetch )运行,并进一步执行代码暂停(尽管不会阻塞),直到异步动作完成为止。 然后,该函数使用return值进行解析,并return一个promise。

Essentially you get to keep your code "inline" without the need for callbacks.  It's async made a bit more simple!

从本质上讲,您可以保持代码“内联”,而无需回调。 异步使它变得更加简单!

将承诺处理转换为await (Converting Promise Handling to await)

There's a good chance you'll want to update your promise code when time becomes available.  Let's walk through updating promise to await:

如果时间允许,您很有可能希望更新您的诺言代码。 让我们逐步了解如何await更新:

// Before: callback city!
fetch('/users.json')
  .then(response => response.json())
  .then(json => {
    console.log(json);
  })
  .catch(e => { console.log('error!'); })

// After: no more callbacks!
async function getJson() {
  try {
    let response = await fetch('/users.json');
    let json = await response.json();
    console.log(json);
  }
  catch(e) {
    console.log('Error!', e);
  }
}

The conversion from loads of thens to await is simple to execute and your code hopefully looks a bit maintainable!

then的加载到await的转换很容易执行,希望您的代码看起来可以维护!

async / await模式

There are a number of ways you can declare async functions.

您可以通过多种方式声明async函数。

匿名异步功能 (Anonymous Async Function)

let main = (async function() {
  let value = await fetch('/');
})();

异步函数声明 (Async Function Declaration)

async function main() {
  let value = await fetch('/');
};

异步功能分配 (Async Function Assignment)

let main = async function() {
  let value = await fetch('/');
};

// Arrow functions too!
let main = async () => {
  let value = await fetch('/');
};

异步函数作为参数 (Async Function as Argument)

document.body.addEventListener('click', async function() {
  let value = await fetch('/');
});

对象和类方法 (Object & Class Methods)

// Object property
let obj = {
  async method() {
    let value = await fetch('/');
  }
};

// Class methods
class MyClass {
  async myMethod() {
    let value = await fetch('/');
  }
}

As you can see, adding async is really easy and accommodates all function creation workflows!

如您所见,添加async非常简单,并且可以容纳所有函数创建工作流程!

错误处理 (Error Handling)

Traditional promise use allows you to use a catch callback to handle rejection.  When you use await, your best bet is using try/catch:

传统的Promise使用允许您使用catch回调来处理拒绝。 当您使用await ,最好的选择是使用try / catch

try {
  let x = await myAsyncFunction();
}
catch(e) {
 // Error!
}

The old try/catch isn't as glamorous as a promise's catch callback but is just as effective.

旧的try / catch不如promise的catch回调那么迷人,但效果却一样。

平行性 (Parallelism)

Google's Jake Archibald make excellent points in the Async functions document about not getting too sequential with your awaits.  The idea is to avoid stacking awaits, when possible, and instead trigger tasks immediately and use await after said tasks are triggered:

Google的Jake Archibald在Async函数文档中提出了很好的观点,即关于await的顺序不是太连续。 这个想法是避免在可能的情况下堆叠等待,而是立即触发任务并触发所述任务使用await


// Will take 1000ms total!
async function series() {
  await wait(500);
  await wait(500);
  return "done!";
}

// Would take only 500ms total!
async function parallel() {
  const wait1 = wait(500);
  const wait2 = wait(500);
  await wait1;
  await wait2;
  return "done!";
}


The first block is bad because the second wait happens after the the first wait completes.  The second block is a better method: trigger both wait calls and then use await ; doing so allows the async functions to happen concurrently!

第一个块不好,因为第二个wait在第一个wait完成后发生。 第二个块是一个更好的方法:触发两个wait调用, 然后使用await ; 这样做允许异步功能同时发生!

Promise.all

One of my favorite functions of the Promise API is Promise.all, which fires a callback when all fetches are complete.  There's no direct async / await equivalent but this post provides a good equivalent:

我最喜欢的Promise API函数之一是Promise.all ,当所有提取完成时,它将触发回调。 没有直接的async / await等价物,但是这篇文章提供了一个很好的等价物:

let [foo, bar] = await Promise.all([getFoo(), getBar()]);

Remember that async / await are essentially the same as promises deep down, so we're simply awaiting the aggregated promise to be resolved!

请记住, async / await与内在的承诺基本相同,因此我们只是在等待汇总的承诺得到解决!

You can now use async and await in all major browsers.  These new keywords are also available within Node.js; older Node.js versions can use the transform-async-to-generator babel plugin to use async and await today.  Promises are still excellent but are made more maintainable with async and await!

现在,您可以在所有主要的浏览器中使用asyncawait 。 这些新关键字在Node.js中也可用。 较旧的Node.js版本可以使用transform-async-to-generator babel插件使用async并立即await 。 承诺仍然非常出色,但是通过asyncawait可以更容易维护!

翻译自: https://davidwalsh.name/async-await

同步等待 异步等待

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值