javascript回调函数抢先一步

javascript回调函数抢先一步,javascript,node.js,Javascript,Node.js,各位,我有以下for循环,在其中我调用另一个模块的vehicles.alertsVid函数,它返回每辆车的状态。结果确实到达了,但是很晚,并且没有正确地添加 写这篇文章的正确方法是什么,这样主for循环就不会领先,并且temp.status会及时写入?:) 调用内部函数时,变量在调用时绑定到调用堆栈。因此,回调函数不会“抢先” 请注意,函数返回函数本身,因此返回双重嵌套。我的一个签名。=) 如果您可以控制从车辆调用的alertsVid函数,您可能希望将整个temp对象传递给它,并让它来处理它,而

各位,我有以下for循环,在其中我调用另一个模块的
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);
}