Node.js: ожидание обратных вызовов в цикле, прежде чем двигаться дальше - PullRequest
8 голосов
/ 20 июля 2011

У меня есть цикл, в котором есть асинхронный вызов с обратным вызовом. Чтобы иметь возможность двигаться дальше, мне нужен обратный вызов для запуска всего цикла в течение всего цикла, чтобы затем отобразить результаты цикла.

Каждый способ, которым я пытался контролировать это, не работает (пробовал Step, Tame.js, async.js и другие) - какие-либо предложения о том, как двигаться вперед?

array = ['test', 'of', 'file'];
array2 = ['another', 'array'];

for(i in array) {
    item = array[i];
    document_ids = new Array();

    for (i2 in array2) {
        item2 = array2[i2];
        // look it up
        mongodb.find({item_name: item2}).toArray(function(err, documents {
            // because of async,
            // the code moves on and calls this back later
            console.log('got id');
            document_ids.push(document_id);
        }))
    }

    // use document_ids
    console.log(document_ids); // shows []
    console.log('done');
}

// shows:
// []
// done
// got id
// got id

1 Ответ

10 голосов
/ 20 июля 2011

Вы регистрируете document_ids до того, как ваши обратные вызовы сработают. Вы должны отслеживать, сколько обратных вызовов вы запустили, чтобы знать, когда вы закончите.

Простой способ - использовать счетчик и проверять счетчик для каждого обратного вызова.

Принимая ваш пример

var array = ['test', 'of', 'file'];
var array2 = ['another', 'array'];
var document_ids = [];

var waiting = 0;

for(i in array) {
    item = array[i];

    for (i2 in array2) {
        item2 = array2[i2];
        waiting ++;

        mongodb.find({item_name: item2}).toArray(
            function(err, document_id) {
                waiting --;
                document_ids.push(document_id);
                complete();
            })
        );
    }
}

function complete() {
    if (!waiting) {
        console.log(document_ids);
        console.log('done');    
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...