1

下面,我尝试评估im.identifybefore console.log(toObtain),但似乎console.log(toObtain)是 after 调用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.
4

3 回答 3

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
};
于 2012-09-22T03:50:27.563 回答
2

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

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

如果您希望订购多个活动,以便它们一个接一个地发生,您需要应用以同步方式(一个接一个)“链接”异步函数的各种技术之一,例如caolan 编写的async 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
于 2012-09-22T03:52:31.643 回答
0

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

编辑:因此,您必须将用户获取的任何代码放入的回调中,之后toObtain = features;

于 2012-09-22T03:24:37.990 回答