ES2017 - Async vs. Yield

前端 未结 4 1513
囚心锁ツ
囚心锁ツ 2020-12-05 12:59

I am confused about the current discussion of adding async functions and the keyword await to the next EcmaScript.

I do not understand why it is necessa

4条回答
  •  不知归路
    2020-12-05 13:38

    By marking a function as async, you're telling JS to always return a Promise.

    Because it will always return a Promise, it can also await on promises inside of its own block. Imagine it like one giant Promise chain - what happens internally to the function gets effectively gets bolted on to its internal .then() block, and what's returned is the final .then() in the chain.

    For example, this function...

    async function test() {
      return 'hello world';
    }
    

    ... returns a Promise. So you can execute it like one, .then() and all.

    test().then(message => {
      // message = 'hello world'
    });
    

    So...

    async function test() {
      const user = await getUser();
      const report = await user.getReport();
      report.read = true
      return report;
    }
    

    Is roughly analogous to...

    function test() {
      return getUser().then(function (user) {
        return user.getReport().then(function (report) {
          report.read = true;
          return report;
        });
      });
    }
    

    In both cases, the callback passed to test().then() will receive report as its first parameter.

    Generators (i.e. marking a function * and using the yield keyword) are a different concept altogether. They don't use Promises. They effectively allow you to 'jump' between different portions of your code, yielding a result from inside of a function and then jumping back to that point and resuming for the next yield block.

    Although they feel somewhat similar (i.e. 'halting' execution until something happens somewhere else), async/await only gives you that illusion because it messes with the internal ordering of Promise execution. It's not actually waiting - it's just shuffling when the callbacks happen.

    Generators, by contrast, are implemented differently so that the generator can maintain state and be iterated over. Again, nothing to do with Promises.

    The line is further blurred because at the current time of writing, support for async/await is scare; Chakracore supports it natively, and V8 has it coming soon. In the meantime, transpilers like Babel allow you to write async/await and convert the code to generators. It's a mistake to conclude that generators and async/await are therefore the same; they're not... it just so happens that you can bastardize how yield works alongside Promises to get a similar result.

    Update: November 2017

    Node LTS now has native async/await support, so you ought never to need to use generators to simulate Promises.

提交回复
热议问题