异步给回调已经调用了错误?

时间:2016-10-26 17:17:56

标签: javascript node.js mean-stack async.js

我正在尝试实现以下方案。但是在执行时我收到错误未捕获错误:已经调用了回调。

任何人都可以找到我做错的事吗?

async.forEachOf(code,function(item, index, done){
    var currentItemId = item.id;    
    var subitemCount = item.subitem;
    for(var k=0; k< subitemCount ; k++){
         $.ajax({
            url: 'api/item' + k,
            success: function(result) {              
             code["allSub"].push(result);
             done();
            },
            error: function(err) {                
                done(err);             
            }
        })
    }
},function(){
    console.log(code);
});

1 个答案:

答案 0 :(得分:1)

问题在于for(var k=0; k< subitemCount ; k++){声明。

请注意,对于每个item.subitem,您正在进行一次ajax调用。并且在每次调用返回之后,您正在调用done()回调。因此,代码实际上多次调用回调(即done())。每次ajax调用一次,每次item.subitem一次。

这就是为什么你有未捕获的错误:已经调用了回调。

为了避免这种情况,您需要制作另一个async.forEachOf而不是

尝试使用:

async.forEachOf(code,function(item, index, doneItem){
    var currentItemId = item.id;    
    var subitemCount = item.subitem;
    async.forEachOf(subitemCount, function (subItem, subItemIndex, subItemDone){
        $.ajax({
            url: 'api/item' + subItemIndex,
            success: function(result) {              
                code["allSub"].push(result);
                subItemDone();
            },
            error: function(err) {                
                subItemDone(err);             
            }
        })
    }, function(err) {
        //Called once all the current item's subItems ajax calls were finished 
        doneItem(err);
    }


},function(){
    //Called once all items in "code" finished their own subItem ajax calls
    console.log(code);
});

如果item.subitem是数值而不是数组,您可以尝试使用async.times

async.forEachOf(code,function(item, index, doneItem){
    var currentItemId = item.id;    
    var subitemCount = item.subitem;
    async.times(subitemCount, function (subItemIndex, subItemDone){
        $.ajax({
            url: 'api/item' + subItemIndex,
            success: function(result) {     
                code["allSub"].push(results);         
                subItemDone();
            },
            error: function(err) {                
                subItemDone(err);             
            }
        })
    }, function(err, results) {
        //Called once all subItem ajax calls were finished
        doneItem(err);
    }


},function(){
    //Called once all items in "code" finished their own subItem ajax calls
    console.log(code);
});