【问题标题】:NodeJS - File Write/Http request truly asychronousNode JS - 文件写入/Http 请求真正异步
【发布时间】:2018-03-15 05:56:38
【问题描述】:

我正在使用节点运行以下打字稿文件:

#!/usr/bin/env node

let Discord = require('discord.js');
let Hook = new Discord.WebhookClient('xxxxxxx', 'xxxxxxxx');

Hook.send("hello")

for (let i = 0; i < 1000000000; i++) {}

发送调用是异步的,但是 Hook 实际上是在循环的最后一次迭代之后发送的。当我用fs.writeFile("result.txt", "Hey there!", function(err) {console.log("The file was saved!");});替换http代码时也是如此@

我怎样才能实现真正异步甚至同步调用该函数。我只想在整个循环执行之前发送 http 请求。

【问题讨论】:

标签: javascript node.js typescript asynchronous synchronous


【解决方案1】:

您可以使用Promises,我们可以使用.then() 等待完成。这样我们就可以继续我们的其他处决:

let Discord = require('discord.js'); let Hook = new 
Discord.WebhookClient('xxxxxxx', 'xxxxxxxx');

Hook.send("hello").then(function(response) {
  for (let i = 0; i < 1000000000; i++) {}
})

【讨论】:

  • 这不是 假设 Hook.send 返回一个 Promise 吗?
  • 是的,如果它不是一个 Promise,我们就必须把它变成一个,这样我们才能使它异步。我曾假设Discord .WebhookClient 已经是一个承诺。不是吗?
  • 在这种情况下,继续:p
【解决方案2】:

如果你的操作可以有回调函数,你可以嵌套回调。

例如

#!/usr/bin/env node

let Discord = require('discord.js');
let Hook = new Discord.WebhookClient('xxxxxxx', 'xxxxxxxx', function callback(err, res) {
    console.log('File saved or async operation finishes here');
    Hook.send("hello");
});

正如您在问题中提到的,您可以先使用fs.writeFile 尝试他。这里的症结在于,传入的回调函数名为callback,在异步操作完成时被调用。然后在该函数内部调用Hook.send,以保证它在第一个函数完成后执行。

一旦开始大量执行此操作,您就会遇到称为回调地狱的情况,在这种情况下,您会遇到嵌套大量回调的情况。

您需要查看async module 或 JS Promises 和 Promise 链接。

【讨论】:

    【解决方案3】:

    Hook.send 会同步执行,但如果它与网络交互,那么它也会执行一些阻塞工作,这些工作将被添加到事件循环中。

    只有在线程执行完同步代码后才会处理事件循环。这就是为什么钩子在循环运行后实际发送的原因。

    如果您想延迟循环直到异步工作完成,那么您需要等待承诺(Hook.send 返回)解决。

    当您使用 TypeScript 时,无论您使用的是什么版本的 Node,您都可以访问 async/await,因此可以重构您的代码。

    async main() {
      await Hook.send("hello");
    
      // continue doing synchronous work
    }
    
    main().catch(err => throw err);
    

    【讨论】:

    • 谢谢这解决了实际问题。承诺不合适,因为我的代码不是基于事件的
    • @Chocolate - 如果你认为 Promise 不适用于这里,那你就有点误会了。它们对于Hook.send() 的任何异步操作都很有用。它与您的代码的其他结构无关。 Promise 是跟踪异步操作中的完成和错误并将它们与其他代码协调的一种方法,这正是您在此处尝试执行的操作 - 因此,以您在评论中所做的方式将它们解散,显然您不了解它们的用处以及它们将如何应用在这里。
    猜你喜欢
    • 1970-01-01
    • 2019-02-07
    • 2018-04-26
    • 1970-01-01
    • 2017-06-01
    • 2018-02-11
    • 1970-01-01
    • 2017-03-31
    • 1970-01-01
    相关资源
    最近更新 更多