【问题标题】:How does async-await work in JavaScript? Does making a function async make it asynchronous?async-await 在 JavaScript 中是如何工作的?使函数异步使其异步吗?
【发布时间】:2019-05-12 06:33:59
【问题描述】:

使函数异步使其异步吗?

我开始使用 async-await 来代替 Promise 链。我做了类似的事情

async function f(){
    let r = await first();
    let d = await sec(r);
    return d;
}

在调用这个函数时,我可以看到所有代码都是异步发生的。但是在我读到的一些较早的文章中,我们无法在 JavaScript 中创建异步函数。那么使函数异步使其异步吗?

【问题讨论】:

  • 一旦它解析了 first() ,它就会转到第二行,即 await sec()。

标签: javascript async-await ecmascript-2017


【解决方案1】:

使函数异步使其异步吗?

不,它会使其返回一个 Promise 并暂停该函数,直到 Promise 在遇到 await 语句时解决。

承诺一种管理异步代码的方式,但不要停止同步,阻塞代码是同步的还是阻塞的。

【讨论】:

    【解决方案2】:

    使函数异步使其异步吗?

    不,它没有。

    是的,我们不能在 javascript 中创建异步函数。我们可以在异步任务之后使用异步函数来执行我们的代码,但代码只会在我们的单线程中执行。

    await 在 async-await 中是异步的,当编译器到达 await 时,它会停止执行并将所有内容推送到事件队列中,并在 async 函数之后继续使用同步代码。示例

    function first() {
        return new Promise( resolve => {
            console.log(2);
            resolve(3);
            console.log(4);
        });
    }
    
    async function f(){
        console.log(1);
        let r = await first();
        console.log(r);
    }
    
    console.log('a');
    f();
    console.log('b');
    

    由于 await 是异步的,因此 await 之前的所有其他事情都照常发生

    a
    1
    2
    4
    b
    // asynchronous happens
    3
    

    【讨论】:

    • 你是在说 不,它没有 但你又在说 异步发生
    • 关于此代码的一些cmets可以找到here
    【解决方案3】:

    Async 和 Await 只是编写 JavaScript Promises 的一种简单方式。但是,在幕后,JavaScript 将代码转换为它在引入 Async 和 Await 之前所做的事情。

    在后台,您的代码示例:

    async function f(){
      let r = await first();
      let d = await sec(r);
      return d;
    }
    

    真的变成了这样的代码:

    function f() {
      return first().then(r => sec(r));
    }
    

    或者更详细的例子:

    function f() {
      return new Promise(
        (resolve, reject) => {
          first().then(
            function(r) {
              return sec(r);
            }
          ).then(
            function(d) {
              resolve(d);
            }
          ).catch(ex) {
            reject(ex);
          }
        }
      );
    }
    

    如您所见,您的代码示例非常更易于阅读。但它可能会令人困惑,因为它看起来就像是同步的。

    【讨论】:

      【解决方案4】:

      使函数异步使其异步吗?

      这取决于你所说的异步是什么意思。

      让我们考虑一个稍微不同的代码版本:

      async function f(){
          let rPromise = first();
          let dPromise = sec(r);
          let r = await rPromise;
          let dPromise = await dPromise;
          return d;
      }
      

      这里因为在第二个 promise 开始之前我们不会 await 第一个 promise,所以这两个可能会同时等待(如果 first() 足够快地返回一个完整的 promise,它们可能不会)。两人可能同时在做事。 rPromise 可能在 dPromise 之前完成,也可能在它之后完成。但是,只有当他们正在做的事情(比如等待来自 Web 服务的 I/O 响应)发生在 JavaScript 本身之外时,他们才会同时做事情。

      在其他一些语言/框架中,我们可能期望两个线程在这里运行,可能在不同的内核上。在 JavaScript 中只有一个线程,并且在 JavaScript 中实际运行的代码(而不是 JavaScript 等待响应的 Web 访问库,或触发延迟的计时器,或其他)只会永远在first()sec() 中运行,但不要同时在两者中运行。如果它们是内部的 awaiting 返回,而另一个正在处理它 awaited 上的内容,那么在另一个函数完成之前不会进行进一步的处理。

      这是asynchronous(这两个不是以固定的顺序发生,一个必须在另一个之前发生)。

      虽然不是多线程的,而且每个中的实际 JavaScript 代码不会同时发生,这在其他一些上下文中称为asychronous

      但在我读到的一些较早的文章中,我们无法在 JavaScript 中创建异步函数。

      首先,直到最近我们甚至无法在 JavaScript 中创建这种异步代码,尽管我们可以通过其他方式创建 Promise。

      其次,虽然它是异步,但它并不是一些来自其他语言和框架的人所认为的异步,异步主要是通过多线程传递的,它具有 JavaScript 所缺乏的两种能力,但也它也缺乏陷阱。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-02
        • 1970-01-01
        • 2017-09-17
        • 2019-01-17
        • 2017-06-13
        • 1970-01-01
        • 2021-01-17
        • 1970-01-01
        相关资源
        最近更新 更多