【问题标题】:handling asynchronous call backs in nodejs在节点 js 中处理异步回调
【发布时间】:2012-06-08 15:15:20
【问题描述】:

我是 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() 的地方。请任何人提供建议。

提前致谢。

【问题讨论】:

    标签: node.js callback


    【解决方案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 方法也可以,因为您可以比较两个数组的长度。

    【讨论】:

    • 更改代码后我仍然面临同样的问题。至少它不是检查 if 条件,而是直接改变 i 值并继续进一步的语句。
    • 我的错,它实际上是--itemsLeft,现在试试。
    【解决方案2】:

    你不能让循环等待,但你可以修改你的代码以获得你期望的行为:

    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});
                }
            });
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2019-02-12
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2017-01-09
      • 2020-03-30
      • 2019-10-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多