如何在 node.js 中创建自定义异步函数?

IT技术 javascript node.js asynchronous
2021-02-20 20:40:02

我不确定 node.js 如何能够实现哪些功能是异步的,哪些不是,以及如何创建自定义异步功能。

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

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

我试过类似的东西,但它没有异步工作。你如何告诉 node.js f 实际上是异步的?

2个回答

注意:这个答案是在 2014 年写的async function,在 Promises 出现之前,并且在 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 混淆。
2021-04-15 20:40:02

只有本机函数(可以访问事件循环)是异步的。您需要调用其中之一来获取回调的异步性。请参阅什么是异步 javascript 函数的简单示例?.

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

只是要清楚你的最后一句话,你不能使函数异步,对吗?
2021-05-07 20:40:02
@MagnusLindOxlund 只能通过调用另一个异步函数,例如setTimeout,但当然这不会使代码的同步部分在后台运行或其他东西。
2021-05-13 20:40:02