2016-05-23 2 views
0

Я нахожу, что в моем коде много чего пишу, и я уверен, что там есть стандартная библиотека, которая делает это намного проще - надеюсь, один лайнер. По сути, я хочу написать обработчик async для массива, который выполняет некоторую асинхронную работу за элемент в массиве и обращается ко всей работе над массивом: (A) после того, как каждый отдельный элемент массива успешно обработан асинхронным способом или (B), если возникла какая-либо ошибка, если возможно, выходить рано, но только так, что мастер-вызов вызывается точно один раз.Какая библиотека или шаблон уменьшает шаблон для этого количества cb до 1 cb?

Надеясь на ответ, который работает как для браузера и узла:

// @items - an array 
// @cb - callback after all of `items` processed, taking an optional Error first argument 
function doForEachAndCb(items, cb) { 
    var exitEarly, tasksRemaining; 
    if (!items || typeof items !== 'object' || !items.length) { 
    cb(); 
    return; 
    } 

    tasksRemaining = items.length; 
    exitEarly = false; 

    function finishOneTask(err) { 
    // finishOneTask() is no-op if previously called with an error passed. 
    if (exitEarly) { 
     return; 
    } 
    if (!!err) { 
     exitEarly = true; 
     cb(err); 
     return; 
    } 
    tasksRemaining--; 
    if (tasksRemaining === 0) { 
     cb(); 
    } 
    } 

    items.map((v) => { 
    try { 
     handleItemAsync(items[v], finishOneTask); 
    } catch (err2) { 
     finishOneTask(err2); 
    } 
    }); 
} 
+0

Соответствующая именованная библиотека [Async.js] (https://github.com/caolan/async) хороша для общих утилит обратного вызова. –

ответ

0

Заканчивать async#map():

async.map(items, (item, callback) => { 
    // do something async 
    ... 
    // when async operation has finished, call 
    // the callback with the mapped value 
    callback(null, value); 
}, (err, mappedItems) => { 
    ... 
}); 

Если у вас нет необходимости строить массив преобразованных значений, вы можете использовать async#each.

Оба async#map() и async#each() также имеют последовательную версию, в которой каждый элемент обрабатываются только после того, как предыдущий этап обработки завершен («обычная» версия обрабатывать все элементы параллельно): async#mapSeries() и async#eachSeries().