javascript回调函数抢先一步
各位,我有以下for循环,在其中我调用另一个模块的javascript回调函数抢先一步,javascript,node.js,Javascript,Node.js,各位,我有以下for循环,在其中我调用另一个模块的vehicles.alertsVid函数,它返回每辆车的状态。结果确实到达了,但是很晚,并且没有正确地添加 写这篇文章的正确方法是什么,这样主for循环就不会领先,并且temp.status会及时写入?:) 调用内部函数时,变量在调用时绑定到调用堆栈。因此,回调函数不会“抢先” 请注意,函数返回函数本身,因此返回双重嵌套。我的一个签名。=) 如果您可以控制从车辆调用的alertsVid函数,您可能希望将整个temp对象传递给它,并让它来处理它,而
vehicles.alertsVid
函数,它返回每辆车的状态。结果确实到达了,但是很晚,并且没有正确地添加
写这篇文章的正确方法是什么,这样主for循环就不会领先,并且temp.status
会及时写入?:)
调用内部函数时,变量在调用时绑定到调用堆栈。因此,回调函数不会“抢先”
请注意,函数返回函数本身,因此返回双重嵌套。我的一个签名。=) 如果您可以控制从车辆调用的
alertsVid
函数,您可能希望将整个temp对象传递给它,并让它来处理它,而不是temp.vid
(该属性从何而来?)
这样,您将传递相同的对象引用,以便在最终处理它时,您将状态添加到右侧的temp
(rightemp
)。这样,它可以在回调中返回右temp
作为参数
您正在初始化一个新对象temp
,并添加name
和plate
。我不认为vid
是temp
上的属性
另外,如果您想等待所有temp
s处理完毕,并在调用最终回调之前保持状态,则可以使用计数器等待它触发。如果你不想这样做,就忽略这些行。。。(我已经用“//回调处理
”进行了注释)
还有。。。修正那些分号P
var numProcessed = 0; // callBack handling
var numToProcess = vehiclesStuff.length; // callBack handling
for (var i = vehiclesStuff.length - 1; i >= 0; i--) {
var temp = {};
temp.name = vehiclesStuff[i].nickname.S;
temp.plate = vehiclesStuff[i].plate.S;
vehicles.alertsVid(temp, function (rightTemp, results, done) {
console.log ("ALERTS",results);
rightTemp.status = results.toString();
done();
processedTemp(); // callBack handling
})
vehicleArray.push(temp);
}
// callBack handling
function processedTemp(){
numProcessed++;
if(numProcessed === numToProcess) callBack();
}
然后,您的vehicles.alertsVid函数将如下所示:
vehicles.alertsVid = function(temp, callBack){
...
callBack(temp, results, done); // using the same temp (object reference) that was passed in!!!
};
这都是假设您可以控制
车辆.alertsVid
功能。您应该熟悉闭包的概念。闭包是捕获任何给定评估/执行链的上下文的强大方式
function callbackClosure(temp){
return function(results, done){
console.log ("ALERTS",results);
temp.status = results.toString();
done();
};
}
for (var i = vehiclesStuff.length - 1; i >= 0; i--) {
var temp = {};
temp.name = vehiclesStuff[i].nickname.S;
temp.plate = vehiclesStuff[i].plate.S;
temp.base = vehiclesStuff[i].base.S;
temp.vin = vehiclesStuff[i].vin.S;
temp.vid = vehiclesStuff[i].vid.S;
vehicles.alertsVid(temp.vid, callbackClosure(temp));
vehicleArray.push(temp);
}
这段代码所做的是创建一个新的上下文,方法是返回一个函数,该函数的作用域由callbackClosure
执行实例限定,其中包含一个特定的传入对象,该对象将保留在其唯一作用域中,直到执行为止
这是假设您的vehicles.alertsVid
执行并在其回调中返回results
对象以及done
函数
在这个问题上了解有关闭包的更多信息:你错过了所有分号,而把一个放在了不属于分号的地方?@elclanrs-啊,这是一个辩论分号的机会。他们不在那里,但我并不想念他们。。。(不,我真的不想对此进行辩论。)虽然代码让它看起来是这样的,但是由于提升的原因,temp不是循环作用域,因此如果传递给alertsVid的函数实际上在以后被调用,它将被调用,所有版本的循环都将使用temp的最终值,而不是单步执行。这就是正在发生的事情吗?“所以主for循环没有领先”-请注意,这不是一个“竞争”情况。您的JS将是单线程的,但可能是
vehicles.alertsVid()
触发了一个异步进程,因此您传递给它的函数将在整个for循环完成并且callback()返回后才会被调用@埃尔克兰斯-是的,我知道。我只是有点傻(如果你能想象的话)。好吧,我希望我的第二个答案能有所帮助。我认为问题不在于结果/完成,而在于温度。事实上,我相当怀疑回调函数应该作为参数接收results/done,因此您的代码可能是错误的,返回的函数应该仍然将results/done作为参数,但外部函数应该将temp作为参数。我现在也在传递temp变量,如果在评估时超出范围。谢谢你指出这一点。我忽略了函数内部的内容,只更改了调用流。@Schien:不管怎样,您仍然在为结果传递未定义的,而不是从回调参数获取它们。我们要说的是函数(t,results,done){return function(){
应该是函数(t){return function(结果,完成){
此方法也要求您能够修改vehicles.alertsVid以接收并返回整个temp对象,并将其作为t返回。如果您不修改vehicles.alertsVid以通过temp对象,则此方法将不起作用。谢谢您,先生。如果我无法控制alertsVid
功能,该怎么办?我已经更新了我的代码,有任何问题吗ggestions?temp.vid=vehiclesStuff[i].vid.S;…忘了在原始贴纸中包含参考昆汀对原始贴子的评论!不幸的是,在您的callbackClosure(temp)之后添加了第二个答案
仍然不起作用……这里有一个要点:我认为您还没有完全掌握要点中异步编程的概念,更不用说javascript了。此外,您仍然没有正确使用分号。:)在要点中,请尝试console.log(temp)在callbackClosure函数返回的函数中。在这里,请观看以下视频:除此之外,我已经尽我所能提供了帮助。看看您是否可以让它工作!;)
vehicles.alertsVid = function(temp, callBack){
...
callBack(temp, results, done); // using the same temp (object reference) that was passed in!!!
};
function callbackClosure(temp){
return function(results, done){
console.log ("ALERTS",results);
temp.status = results.toString();
done();
};
}
for (var i = vehiclesStuff.length - 1; i >= 0; i--) {
var temp = {};
temp.name = vehiclesStuff[i].nickname.S;
temp.plate = vehiclesStuff[i].plate.S;
temp.base = vehiclesStuff[i].base.S;
temp.vin = vehiclesStuff[i].vin.S;
temp.vid = vehiclesStuff[i].vid.S;
vehicles.alertsVid(temp.vid, callbackClosure(temp));
vehicleArray.push(temp);
}