【问题标题】:Javascript async function is waiting for response without awaitJavascript异步函数正在等待响应而不等待
【发布时间】:2018-10-08 11:20:29
【问题描述】:

我对 JavaScript 的异步行为概念不熟悉。

下面的代码让我很困惑。根据我的概念,函数 b 应该在等待函数完成执行之前返回,因为我没有告诉它使用“等待”等待。 但我得到的输出是这样的: 前 然后等待 6 秒 后 在b之后

预期输出: 前 后 在 b 之后 无需等待 6 秒 这是代码:

function wait(ms)
{

  var start = new Date().getTime();

  var end = start;

  while(end < start + ms) {    

    end = new Date().getTime();

    }
}

async function b () {
  console.log('before');
  wait(6000);
  console.log('after');
}

async function c () {
b()
console.log('after b');
}

c();

请帮助我更好地理解这个概念

【问题讨论】:

  • 它等待的原因是因为wait函数内部的循环是一个“忙循环”。它绑定了活动的“线程”,因此异步代码不会暂停。
  • 我对这个预期的输出感到困惑:before after after b without waiting for 6 secondsbeforeafter 之间应该总是有 6 秒的暂停。但是,before b 可能会根据所使用的等待方法出现在不同的位置。
  • @cleberz 据我所知(我可能错了,如果我错了,请纠正我)在 b 打印“之前”之后,执行线程将继续执行等待函数,但因为 b 是异步函数所以'after'会立即打印。为了停止这种情况,我们需要使用等待,所以我们告诉执行线程等待,直到响应从等待函数返回
  • async 关键字不会使函数异步。它唯一能做的就是允许你在函数中使用 await 关键字(await 关键字在其他任何地方都无效)
  • @slebetman 好的,现在我明白了。那么如何以及何时决定一个呼叫是否为异步呼叫?感谢 bdw 的回答

标签: node.js asynchronous async-await


【解决方案1】:

这很容易理解。函数wait() 是同步的。

async 关键字不会使函数异步。它只允许您在标有async 的函数中使用await 关键字。


那么你怎么知道一个函数是异步的还是同步的呢?最简单的方法是阅读文档。

Javascript 几乎没有任何特性可以告诉你函数是同步的还是异步的。甚至回调的存在也不是一个信号。例如,Array.prototype.sort() 接受回调但完全同步。 async 关键字是朝着正确方向迈出的重要一步,它可以表明函数是异步的,但正如您自己所证明的那样,这取决于函数的作者是否理解 async 关键字的作用。

好处是 javascript 中的文档与 Java 或 C++ 等其他语言相比往往非常好,因为通常没有自动文档(即使您在 js 中使用自动文档系统,您也需要手动为其编写 cmets)。在 README 文件中编写详细、清晰的文档是一种普遍的文化,以便 npm 为库的用户挑选它。


那么如何在 javascript 中编写异步函数呢?

一般只有两种方法:

  1. 使用异步函数。例如setTimeout()fetch()

    function waitOneSecond () {
        return new Promise(functionn (ok,err) {
            setTimeout(ok,1000);
        });
    }
    
  2. 用 C 编写。对于 node.js,您可以使用 Addons API 在 C/C++ (https://nodejs.org/api/addons.html) 中实现模块,Chrome 有 NaCl (https://developer.chrome.com/native-client) 等。就像@987654333 这样的功能@、fetch() 等已实现。

【讨论】:

    【解决方案2】:

    请看这个例子:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

    如前所述,async 关键字允许您使用 await。从技术上讲,它做了更多的事情,但现在让我们忽略它。

    该示例显示了async 函数awaits 在它连续之前解决的Promise(它确实允许异步编程)。基本上,await 允许您在处理异步函数的同时编写同步代码。

    尝试使用示例(例如删除等待)。这将导致代码不等待承诺并返回承诺而不是承诺的解析值。

    如果您想深入了解异步编程,最好的选择是深入了解Promises。这些为您提供了执行此操作的接口。

    这个概念相当简单。您做一些工作并在完成后调用回调(成功时解决,或失败时拒绝)。理解界面可能有点困难,但 MDN 有很好的文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

    【讨论】:

      猜你喜欢
      • 2023-03-13
      • 2023-03-10
      • 2019-10-21
      • 1970-01-01
      • 2019-05-10
      • 2020-12-03
      • 1970-01-01
      • 2011-09-03
      • 2019-06-16
      相关资源
      最近更新 更多