处理nodejs中的异步回调

时间:2012-06-07 13:15:24

标签: node.js callback

我是nodejs的新手。在nodejs级别处理回调非常困难。我有这样的代码,

getItems(request,function(jsonObject){
     var itemData={};
     var itemDetails=new Array();
     for(var i=0;i < jsonObject.length;i++){
         getItemDetails(jsonObject[i].value.item_id,function(jsonObject){
            itemDetails.push(jsonObject);
         });
    }
    itemData["itemDetails"]=itemDetails;
    response.contentType("application/json");
    response.send({"data":itemData});
});

在执行上面的代码时,for循环继续从getItemDetails方法获取回调并将响应发送到客户端。我的要求是循环将等待从getItemDetails获得回调,然后响应应该发送。 我已尝试使用process.nextTick(),但我无法找到我必须使用该process.nextTick()..请任何人提供建议。

提前致谢。

2 个答案:

答案 0 :(得分:1)

只有在获得所有项目后才需要发送响应,因此请修改代码:

getItems(request,function(jsonObject) {
    var itemData = {},
        itemDetails = [],
        itemsLeft = len = jsonObject.length,
        i;

    function sendResponse(itemDetails) {
        itemData["itemDetails"] = itemDetails;
        response.contentType("application/json");
        response.send({ "data": itemData });
    }

    for (i = 0; i < len; i++) {
        getItemDetails(jsonObject[i].value.item_id, function(jsonObject) {
            itemDetails.push(jsonObject);
            // send response after all callbacks have been executed
            if (!--itemsLeft) {
                sendResponse(itemDetails);
            }
        });
    }
});

注意:我在这里使用itemLeft,因为它是解决这类问题的更通用的方法,但Ianzz方法也可以,因为你可以比较两个数组的长度。

答案 1 :(得分:0)

您无法让循环等待,但您可以修改代码以获得您期望的行为:

getItems(request,function(outerJsonObject){
    var itemData={};
    var itemDetails=new Array();
    for(var i=0;i < outerJsonObject.length;i++){
        getItemDetails(jsonObject[i].value.item_id,function(innerJsonObject){
            itemDetails.push(innerJsonObject);
            if (itemDetails.length == outerJsonObject.length) {
                // got all item details
                itemData["itemDetails"]=itemDetails;
                response.contentType("application/json");
                response.send({"data":itemData});
            }
        });
    }
});