NodeJS Async: обратный вызов уже вызван?

#javascript #node.js #asynchronous

#javascript #node.js #асинхронный

Вопрос:

Я использую асинхронный модуль в узле.JS для отслеживания моих асинхронных вызовов. Однако я получаю сообщение об ошибке — «Обратный вызов уже вызван». Кто-нибудь может мне здесь помочь?

 async.each(data['results'], function(result, done) { 
    if (result['twitter_id'] !== null) { //Isolate twitter handle
        var param = { "user.screen_name": result['twitter_id']}
        db.test4.find( param, function(err, users) {
            if( err ) {
                return done(err);
            } else if (!users) {
                res.send("No user found");
            } else {
                users.forEach( function(Result) { 
                    twitter_ids.push(Result);
                    //console.log(Result);
                    done();
                });
            }
        });
    }
}, function(err) {  
    if (err) {
        throw err
    }
    res.send(twitter_ids);
});
 

Комментарии:

1. вы вызываете done() на каждой итерации цикла forEach . вы должны переместить done за пределы этого цикла, и это сработает. вы также должны убедиться, что функция done() также вызывается в ветке «else if».

2. Я никогда не использовал модуль Async, но, просто взглянув на ваш код, похоже, что Вы запускаете done() (т. Е. Ваш обратный вызов) несколько раз в цикле

Ответ №1:

Вы вызываете res.send(«Пользователь не найден»); каждый раз, когда не удается загрузить. Однако вы можете не загрузиться несколько раз.

Решение состоит в том, чтобы поместить весь ваш код ответа в окончательный обратный вызов, а не в каждый обратный вызов.

 async.each(data['results'], function(result, done) { 
    if (result['twitter_id'] !== null) { //Isolate twitter handle
        var param = { "user.screen_name": result['twitter_id']}
        db.test4.find( param, function(err, users) {
            if( err ) {
                done(err);
            } else if (!users) {
                done(new Error("No user found"));
            } else {
                users.forEach( function(Result) { 
                    twitter_ids.push(Result);
                    //console.log(Result);
                });
                done();
            }
        });
    } else {
      done();
    }
}, function(err) {  
    if (err) {
        return next(err);
    }
    res.send(twitter_ids);
});
 

Комментарии:

1. Хотя я согласен, что это тоже проблема, я считаю, что ошибка («Обратный вызов уже вызван.») возникает из-за перебора done() в else . Вероятно, OP не хочет выполнять обратный вызов ( done ) несколько раз.

2. ах, ты прав. Это и то, и другое, но похоже, что это выдает ошибку, исправленную сейчас.

3. Да, не уловил этого, ха-ха. Спасибо вам всем! 🙂

4. Вы должны отправить return наконец вместо отправки в каждом условии