下面,我尝试在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.
答案 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;