2

这个问题可能是重复的。我是 node.js 和异步编程回文的菜鸟。我已经谷歌搜索并看到了很多这方面的例子,但我仍然有点困惑。

好的,从谷歌搜索中我了解到所有回调都是异步处理的。例如,让我们从 node.js api中获取readfile函数

fs.readFile(filename, [options], callback) // 这里的回调会异步处理 fs.readFileSync(filename, [options])

  var fs = require('fs');

    fs.readFile('async-try.js' ,'utf8' ,function(err,data){
        console.log(data);   })

    console.log("hii");

上面的代码会先打印 hii 然后再打印文件的内容。

所以,我的问题是:

  1. 所有回调都是异步处理的吗?
  2. 下面的代码不是异步的,为什么以及如何制作它

    function compute(callback){
     for(var i =0; i < 1000 ; i++){}
     callback(i);
    
    }
    
    function print(num){
     console.log("value of i is:" + num);
    }
    
    
    compute(print);
    console.log("hii");
    
4

4 回答 4

4

Are all callbacks handled asynchronously?

Not necessarily. Generally, they are, because in NodeJS their very goal is to resume execution of a function (a continuation) after a long running task finishes (typically, IO operations). However, you wrote yourself a synchronous callback, so as you can see they're not always asynchronous.

The below code is not asynchronous, why and how do I make it?

If you want your callback to be called asynchronously, you have to tell Node to execute it "when it has time to do so". In other words, you defer execution of your callback for later, when Node will have finished the ongoing execution.

function compute(callback){
 for (var i = 0; i < 1000; i++);

 // Defer execution for later
 process.nextTick(function () { callback(i); });
}

Output:

hii
value of i is:1000

For more information on how asynchronous callbacks work, please read this blog post that explains how process.nextTick works.

于 2013-06-13T15:01:28.557 回答
3

不,这是一个常规的函数调用。

除非强制,否则回调不会是异步的。一个好的方法是在setTimeout0 毫秒内调用它,例如

setTimeout(function() { 
   // Am now asynchronous
}, 0);

通常,当调用函数涉及在服务器上发出新请求(例如打开一个新文件)时,回调是异步的,并且在等待它完成时停止执行是没有意义的。

于 2013-06-13T14:55:09.233 回答
2

下面的代码不是异步的,为什么以及如何制作它?

function compute(callback){
  for(var i =0; i < 1000 ; i++){}
  callback(i);
}

我将假设您的代码试图说,“我需要做 1000 次,然后在一切完成后使用我的回调”。

即使你的 for 循环在这里也不起作用,因为想象一下:

function compute(callback){
  for(var i =0; i < 1000 ; i++){
    DatabaseModel.save( function (err, result) {
      // ^^^^^^ or whatever, Some async function here.
      console.log("I am called when the record is saved!!");
    });
  }
  callback(i);
}

在这种情况下,您的 for 循环将执行保存调用,而不是等待它们完成。因此,在您的示例中,您可能会得到类似的输出(取决于时间)

I am called when the record is saved
hii
I am called when the record is saved
...

为了让您的计算方法仅在一切真正完成时调用回调 - 所有 1000 条记录都已保存在数据库中 - 我会研究async Node 包,它可以为您轻松完成此操作,为您提供许多异步问题的模式'将在 Node.js 中面对。

因此,您可以将计算函数重写为:

function compute(callback){
  var count = 0
  async.whilst(
     function() { return count < 1000 },
     function(callback_for_async_module) {
        DatabaseModel.save( function (err, result) {
            console.log("I am called when the record is saved!!");
            callback_for_async_module();
            count++;
        });
     },
     function(err) {
       // this method is called when callback_for_async_module has
       // been called 1000 times

       callback(count);
  );
  console.log("Out of compute method!");
}

请注意,您的计算函数的回调参数将在console.log("Out of compute method"). 这个函数现在是异步的:应用程序的其余部分不会等待compute完成。

于 2013-06-13T15:15:56.530 回答
0

您可以将每个回调调用放在一毫秒的超时内,这样当有一个空闲线程并且所有同步任务都完成时,它们将首先执行,然后处理器将通过要执行的超时堆栈工作。

于 2013-06-13T14:53:31.513 回答