2017-01-26 3 views
0

Я пытаюсь понять функцию async each(coll, iteratee, callback) для выполнения функции параллельно для каждого элемента массива. Из асинхронных документов я понимаю, что обратный вызов будет выполняться только один раз (когда будет выполняться функция iteratee для каждого элемента массива).Async каждая функция

И в случае ошибки в функции итерации вызов callback('some error message') немедленно вызовет функцию обратного вызова с сообщением об ошибке.

Ниже приведен пример из асинхронных документаций для каждой функции

каждого (Coll, iteratee, обратный вызов)

// assuming openFiles is an array of file names 
async.each(openFiles, function(file, callback) { 

    // Perform operation on file here. 
    console.log('Processing file ' + file); 

    if(file.length > 32) { 
     console.log('This file name is too long'); 
     callback('File name too long'); 
    } else { 
     // Do work to process file here 
     console.log('File processed'); 
     callback(); 
    } 
}, function(err) { 
    // if any of the file processing produced an error, err would equal that error 
    if(err) { 
     // One of the iterations produced an error. 
     // All processing will now stop. 
     console.log('A file failed to process'); 
    } else { 
     console.log('All files have been processed successfully'); 
    } 
}); 

То, что я не в состоянии понять, что такой же вызов обратного вызова() без аргументов, мне очень странно, что мы вызываем callback() без аргумента, когда в функции iterate нет ошибки. Что вызывает звонок callback() or callback(null) в случае отсутствия ошибок.

Не можем ли мы просто удалить те callback() or callback(null), когда мы на самом деле хотим вызвать обратный вызов только один раз (когда функция итерации выполняется для всех элементов массива), а не для каждого элемента массива.

ответ

3

Что вызывает звонок callback() or callback(null) в случае отсутствия ошибок.

Вызов callback без аргументов или с null сигналов async.each, что функция iteratee закончил выполнение по этому пункту (file в случае примера). Когда все функции iteratee вызвали их соответствующие callback, или один из них передает ошибку в его обратный вызов, async.each вызовет исходную функцию callback, переданную ей.

Чтобы подробно остановиться на этом, async.js предназначен для обработки асинхронных функций. Выгода (или проблема, в зависимости от того, как вы смотрите на нее), асинхронной функции заключается в том, что нет способа сказать, когда она закончит выполнение. Способ справиться с этим состоит в том, чтобы передать асинхронной функции другую функцию, callback, для выполнения, когда она будет завершена. Асинхронная функция может передавать любые ошибки, с которыми она сталкивается, или любые данные, которые она получает, с исходной функцией вызова через функцию callback. Например, fs.readFile передает прочитанные данные файла, и любые ошибки, через функцию callback, передаются.

мы не можем просто удалить те callback() or callback(null), когда мы на самом деле означает вызвать функцию обратного вызова только один раз (когда iteratee функция выполняется для всех элементов массива), а не для каждого элемента массива.

Нет, потому что async.js должен считать функцию iteratee является asynchorous, и, следовательно, он должен ждать его, чтобы его callback. callback, переданный в async.each, вызывается только один раз.

Путаница может быть вызвана именами переменных. Отдельная функция callback предназначена только для вызова. Функция callback перешла на async.each не то же самое callback перешла на iteratee. Каждый раз, когда вызывается iteratee со значением в coll, передается новая функция callback. Этот звонок iteratee должен только вызывать пройденный callback один раз (async будет выдавать ошибку в противном случае). Это позволяет async отслеживать, вызвал ли вызов функцию iteratee свой callback, и дождитесь, пока остальные вызовут соответствующие callback. Когда все функции callback вызываются, async.each знает, что все асинхронные вызовы функций завершены, и что он может вызвать исходный callback, переданный ему.

Это один из трудных аспектов создания документов. Они должны быть достаточно краткими, чтобы разработчик мог быстро получить информацию от них, а также включить достаточно подробностей, чтобы они могли объяснить концепцию или функцию. Иногда это трудно сбалансировать.

+0

Спасибо @hargasinski, у меня есть одна путаница, когда мы вызываем callback(), когда нет ошибки в функции iteratee, похоже, что мы фактически выполняем функцию обратного вызова (третий аргумент async.each) для каждого элемента –

+0

Да , Я вижу, как это может сбивать с толку. Вы можете переименовать аргументы как 'function (err, fileCallback)', а затем вызвать 'fileCallback();' или 'fileCallback ('File name too long')', чтобы сделать его немного понятным. В этом примере переменные имеют одно и то же имя, но представляют разные вещи. – hargasinski

+0

Спасибо, приятель, теперь я понял. –

0

Вызов обратного вызова без аргументов добавляет счетчик внутри функции .each. Этот счетчик, когда полный - это то, что на самом деле вызывает ваш обратный вызов. Без этого он никогда не узнает, когда это закончится.

Смежные вопросы