如何指定评估node.js函数的顺序?

时间:2012-09-22 03:22:20

标签: node.js

下面,我尝试在im.identify之前评估console.log(toObtain),但似乎在console.log(toObtain)之后调用im.identify。如何确保按照我希望它们被调用的顺序调用函数?

var toObtain; //I'm trying to set the value of this variable to features (inside the callback).

var im = require('imagemagick');
im.identify('kittens.png', function(err, features){
  if (err) throw err
  //console.log(features);
  toObtain = features;
  console.log(toObtain); //this prints { format: 'PNG', width: 400, height: 300, depth: 8 }
})

console.log(toObtain); //This function call is evaluated BEFORE im.identify, which is exactly the opposite of what I wanted to do.

3 个答案:

答案 0 :(得分:2)

这就是节点的工作原理。这是正常的异步行为。

为了避免在使用节点时疯狂,重要的是要将每个具有特定用途的功能分解。每个函数都会根据需要调用下一个传递参数。

var im = require('imagemagick');

var identify = function () {

      im.identify('kittens.png', function(err, features){

         doSomething(features) // call doSomething function passing features a parameter.

      })

}(); // this is the first function so it should self-execute.

var doSomething = function (features) {

       var toObtain = features;

       console.log(toObtain) //or whatever you want to do with toObtain variable
};

答案 1 :(得分:2)

异步意味着事情在准备就绪时发生(彼此之间没有任何同步关系。)

这意味着如果您希望打印或以其他方式操作异步函数中创建的值,您必须在其回调中执行此操作,因为这是唯一保证该值可用的位置。

如果您希望订购多个活动,以便它们一个接一个地发生,您将需要应用以同步方式(一个接一个)“链接”异步函数的各种技术之一,例如{{3}由caolan编写的javascript库。

在您的示例中使用async,您将:

var async=require('async');

var toObtain;

async.series([

  function(next){ // step one - call the function that sets toObtain

    im.identify('kittens.png', function(err, features){
      if (err) throw err;
      toObtain = features;
      next(); // invoke the callback provided by async
    });

  },

  function(next){ // step two - display it
    console.log('the value of toObtain is: %s',toObtain.toString());
  }
]);

这样做的原因是因为异步库提供了一个特殊的回调函数,用于移动到当前操作完成时必须调用的系列中的下一个函数。

有关详细信息,请参阅async文档,包括如何通过next()回调将值传递给系列中的下一个函数以及作为async.series()函数的结果。

可以使用以下命令将async安装到您的应用程序中:

npm install async

或全局,因此它可用于所有nodejs应用程序,使用:

npm install -g async

答案 2 :(得分:0)

这是正常的,因为im.identify接缝是异步的(它需要回调)。因此,回调可以在之后执行下一行。

编辑:因此,在toObtain = features;

之后,您必须将用户的任何代码设置为 IN 您的回调