【问题标题】:How do you create custom asynchronous functions in node.js?如何在 node.js 中创建自定义异步函数?
【发布时间】:2019-12-29 10:24:16
【问题描述】:

我不确定 node.js 是如何实现异步函数和非异步函数的,以及如何创建自定义异步函数。

假设我想创建一个自定义异步函数。如果仅仅因为我将我的最后一个参数调用到异步函数回调或 cb 中,它只会知道它是一个异步函数,我会感到惊讶:

function f(arg1, callback){
  //do stuff with arg1
  arg1.doStuff()
  //call callback
  callback(null, arg1.result());
}

我尝试了类似的方法,但它不能异步工作。如何告诉 node.js f 实际上是异步的?

【问题讨论】:

  • 只有原生函数(可以访问事件循环)是异步的。你需要给其中一个打电话。如果您不使用任何函数,则几乎没有理由使您的函数异步。

标签: javascript node.js asynchronous


【解决方案1】:

注意:这个答案写于 2014 年,在 async function 存在之前,并且在 Promises 流行之前。虽然同样的原则也适用,但我建议您先阅读 Promises,然后再尝试了解它们与“传统”回调驱动的异步函数的关系。


要创建一个异步调用其回调的函数,您必须在其上使用一些平台提供的异步原语(通常与 IO 相关) - 计时器、从文件系统读取、发出请求等。

例如,这个函数接受一个回调参数,并在 100 毫秒后调用它:

function asyncFn(callback) {
  setTimeout(() => {
    callback();
  }, 100);
}

在不需要时使函数异步的一个可能原因是为了 API 的一致性。例如,假设您有一个发出网络请求并缓存结果以供以后调用的函数:

var cache = null;
function makeRequest(callback) {
  if (!cache) {
    makeAjax(result => {
      cache = result;
      callback(result);
    });
  } else {
    callback(cache);
  }
}

问题是,这个函数是不一致的:有时是异步的,有时不是。假设您有这样的消费者:

makeRequest(result => doSomethingWithResult(result));
doSomethingElse();

doSomethingElse 函数可以在doSomethingWithResult 函数之前或之后运行,具体取决于结果是否被缓存。现在,如果您在makeRequest 函数上使用异步原语,例如process.nextTick

var cache = null;
function makeRequest(callback) {
  if(!cache) {
    makeAjax(result => {
      cache = result;
      callback(result);
    });
  } else {
    process.nextTick(() => callback(cache));
  }
}

调用始终是异步的,doSomethingElse 始终在 doSomethingWithResult 之前运行。

【讨论】:

  • 我会更改函数的名称 - async 与新版本的 ECMAScript 混淆。
【解决方案2】:

只有本机函数(可以访问事件循环)是异步的。您需要调用其中一个来获得回调的异步性。见What is a simple example of an asynchronous javascript function?

如果您不使用任何函数,则几乎没有理由使您的函数异步。

【讨论】:

  • 只是为了清楚你的最后一句话,你不能使函数异步,对吧?
  • @MagnusLindOxlund 只能通过调用另一个异步函数,例如setTimeout,但这当然不会使代码的同步部分在后台运行。
猜你喜欢
  • 2015-11-18
  • 2018-09-14
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 2011-02-22
  • 2014-07-08
相关资源
最近更新 更多