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

how to create a custom asynchronous function in node.js

本文关键字:创建 自定义 异步 函数 js node      更新时间:2023-09-26

我正在尝试做类似的事情。

function fun1(){
  for(var j=0;j<20;j++)
  {
    var n = j;
    console.log("i= "+n);
  }
}
function fun2()
{
  console.log("In Callback");
}  
fun1();
fun2();

到目前为止运行良好,产量如预期。

但是,我想异步调用函数fun1()fun2(),这意味着fun2()fun1()之前调用,与fun2()相比,fun1()将需要一些时间来完成执行。

我该如何做到这一点,Node.js提供异步函数,是已经定义的函数只能异步还是我们可以根据需要制作。

在JavaScript中有多种方法可以实现这一点(不是特定于节点的,但有一些模块可以让你的生活更轻松(:


回调

它们在某种程度上是延续,遗憾的是开发人员一直在手动处理它们(编译器过去常常自己处理(。但它们有效:

function callee(callback) {
  setTimeout(function() {
    callback(null, 'finished!');
  }, 2000);
}
function caller() {
  document.write('started!');
  callee(function(err, result) {
    document.write(result);
  });
}
caller();

在节点环境中,用回调的第一个参数(如callback(new Error("something wrong!"))(指示错误是很常见的。


承诺

由于回调在嵌套时会变得很难看(想象一下有10-20个回调,你在调试时会被搞砸(,所以出现了promise的想法。您可能知道它们是java中的Futures。它们是ES6内置的,您可以在npm i promise的节点环境中预先使用它们——许多客户端框架(例如jQuery、AngularJS(都有自己的实现。最初有Q.

var Promise = require('promise');
function callee() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve('finished!');
    }, 1000);
  });
}
function caller() {
  document.write('started!');
  callee().then(function(result) {
    document.write(result);
  });
}
caller();


发电机

ES6有发电机。你可能从蟒蛇那里知道它们。

它们还提供了异步性,因为一旦计算出新值,它们就会yield

我建议阅读学习ES2015了解更多信息。

我个人的观点是永远不要使用生成器,因为它们严重干扰了承诺,使调试变得非常困难


异步/等待

ES7将使async/await的生活更加轻松。您基本上可以说,一个函数将异步执行,并且您希望等待结果(一旦您处于异步函数中(。ES7异步函数是一个很好的开始。这就像

async function callee() {
  return (() => {
    return new Promise((resolve, reject) => {
      setTimeout(() => resolve('finished!'), 1000);
    })
  })();
}
async function caller() {
  document.write('started!');
  document.write(await callee());
}
// the global async wrapper
(async function() {
  caller();
})();

我试图提供@Dominik Schreiber的答案的更好版本

async function callee() {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve('finished!'), 1000);
  })
}
async function caller() {
  console.log('started!');
  console.log(await callee());
}
caller();

您可以使用向事件que添加回调

 process.nextTick(callback);

不要那样做,这几乎从来都不是你想要的。JavaScript是单线程的,所以添加回调仍然会阻止对f2的调用。如果您有一个函数需要很长时间才能在子进程中运行,甚至更好,请为它创建一个单独的微服务。