由于异步调用而未定义

时间:2014-05-25 15:59:58

标签: node.js asynchronous callback return synchronous

我在这里遇到了一些问题。我正在使用NodeJS的后端为Sencha Touch应用程序工作,并且在某些时候我正在调用一个函数,但是在获得该函数返回语句之前,我将进入下一行代码。

这是我的代码......

.... for loop ....
        if(resultSet[k].id_bus == busDocs[n].id_bus && resultSet[k].id_bus_variation == busDocs[n].id_bus_variation){
            resultSet[k].s_origin_description = busDocs[n].s_origin_description;
            resultSet[k].s_eta = vehicle != null ? getVehicleETA(db, vehicle) : 'Unknown';
            console.log('after getting eta');
            resultSet[k].s_destination_description = busDocs[n].s_destination_description;
        }
    }
}
res.send(JSON.stringify(resultSet));
....

这是我的getVehicleETA函数......

getVehicleETA = function(db, vehicle){
    var position = vehicle.position;

    function compare(a,b) {
      if (a.n_stop_number < b.n_stop_number)
         return -1;
      if (a.n_stop_number > b.n_stop_number)
        return 1;
      return 0;
    }

    db.get('busstops').find({$query:{$and:[{id_bus: vehicle.id_bus}, {id_bus_variation: vehicle.id_bus_variation}]},$orderBy:{n_stop_number: 1}},function(e, docs){
        var distance = 0;
        if(docs.length != 0){
            docs.sort(compare);
            var nextBusStop = null;
            for(var i=0; i<docs.length; i++){
                if(i+1 < docs.length){
                    var routeSegmentLength = Math.sqrt(Math.pow(docs[i +1].coord_x - docs[i].coord_x, 2) + Math.pow(docs[i +1].coord_y - docs[i].coord_y, 2));
                    var firstStopDistance = Math.sqrt(Math.pow(vehicle.coord_x - docs[i].coord_x, 2) + Math.pow(vehicle.coord_y - docs[i].coord_y, 2));
                    var secondStopDistance = Math.sqrt(Math.pow(vehicle.coord_x - docs[i +1].coord_x, 2) + Math.pow(vehicle.coord_y - docs[i +1].coord_y, 2));
                    if(nextBusStop != null){
                        distance += routeSegmentLength;
                    }

                    if(secondStopDistance < routeSegmentLength && firstStopDistance < routeSegmentLength){    
                        nextBusStop = docs[i+1];
                    }
                }
            }
            console.log(((distance/(1000 * vehicle.speed)) * 60))
            return ((distance/(1000 * vehicle.speed)) * 60);
        }
    });
}

如果这项工作正常,我必须首先看getVehicleETA的{​​{1}},然后console.log,但我会反过来看到它。我知道这实际上是正确的行为,因为它没有阻塞线程并继续在代码中继续运行,但这对我不起作用,因为我甚至在获得console.log('after getting eta');结果之前发送了resultSet,并且在发送之前,我需要getVehicleETA个项目设置resultSet属性。

这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

正确的方法是在getVehicleETA函数中进行回调。

让我告诉你一个例子:

getVehicleETA = function(db,vehicle,callback){
    /*do some stuff*/
    //return the result in callback.
    callback(result); 
}

resultSet[k].s_origin_description = busDocs[n].s_origin_description;
if(vehicle!=null){
    getVehicleETA(db,vehicle,function(result){
        resultSet[k].s_eta = result;            
        nextAction()
    });
}else{
    resultSet[k].s_eta = "unknown";
    nextAction();
}

function nextAction (){
    console.log('after getting eta');
    resultSet[k].s_destination_description = busDocs[n].s_destination_de
    res.send(JSON.stringify(resultSet));
}

希望这适合你。

答案 1 :(得分:0)

您正在调用异步函数,就好像它是同步的一样。此外,从异步函数的回调中返回值是没有意义的。您必须将回调传递给函数,然后使用数据库中的值在数据库回调中调用该回调。

您应该考虑使用async模块来帮助您在循环中处理异步函数调用。