Я пытаюсь реализовать способ загрузки файлов асинхронно. У меня есть процесс, который я хочу применить к каждому элементу моего массива. Я беру имя каждого элемента, вызываю API для получения дополнительной информации об этом, затем отправляю его в утилиту для преобразования текста в речь и загружаю полученный файл wav
в экземпляр S3.node js - многозадачность для каждого элемента массива
Я не могу найти способ сделать это асинхронно и дождаться завершения всех этих действий.
Я могу сделать это в серии, но это занимает много времени (12 минут для 30 файлов (по 2 мб каждого файла)).
Я попытался реализовать асинхронный путь, который занимает около 5 минут (на 7 минут меньше), но я боюсь, что проблема связана с сеткой?
Функция применяется к каждому элементу: пример
function doAll(c, lan, country, fileName, callback){
getNews(c, lan)
.then(function(newsResults){
getWavFile(newsResults, lan, fileName)
.then(function(wavResults){
uploadToS3(country,lan,fileName)
.then(function(s3Results){
return callback("done");
}, function(s3err){
console.log('s3 error: ',s3err);
return callback("done");
})
}, function(waverr){
console.log('wav error: ',waverr);
})
}, function(newserr){
console.log('news error: ',newserr);
})
}
массива:
var arr = [
{
_id: '5769369ba2d42fd82ca4d851',
Name: 'Sports',
Order: 1,
Color: 'White',
Description: 'ספורט',
UpdatedDate: '2016-07-28T07:44:47.906Z',
CreatedDate: '2016-06-21T12:44:11.468Z',
Country: 'IL',
Langs: [
{
Name: 'Sports',
IsoCode: 'en',
Url: 'SportsJSON',
_id: '576b93486c7a9ff025275836'
},
{
Name: 'ספורט',
IsoCode: 'iw',
Url: 'HebrewSportsJSON',
_id: '576be6ad56126ccc25852613'
}
]
},
{
_id: '576bf4eb28176a3e5ce15afa',
Name: 'Top Stories',
Description: 'הכותרות',
Color: 'ww',
Order: 1,
UpdatedDate: '2016-07-10T12:01:26.713Z',
CreatedDate: '2016-06-23T14:40:43.435Z',
Country: 'IL',
Langs: [
{
Name: 'כותרות',
Url: 'HebrewTopStoriesJSON',
IsoCode: 'iw',
_id: '576bf52228176a3e5ce15afb'
},
{
Name: 'Top Stories',
IsoCode: 'en',
Url: 'TopStoriesJSON',
_id: '576bf94d28176a3e5ce15afd'
}
]
},
{
_id: '5756d5d6c4a3dfe478b16aa2',
Description: 'Nation Channel',
Order: 1,
Color: 'blue',
Code: 'Nation',
Name: 'Nation',
UpdatedDate: '2016-06-24T22:23:07.198Z',
CreatedDate: '2016-06-07T14:10:30.699Z',
Country: 'US',
Langs: [
{
Name: 'Nation',
IsoCode: 'en',
Url: 'NationJson',
_id: '576db2cb28176a3e5ce15b02'
}
]
}
]
Мой асинхронной путь:
var array = [] // see the example how array look like
var newArray= [];
console.log('start uploading files time:', new Date());
for (var i = 0; i < array.length; i++) {
var list = array[i].Langs;
for (var j= 0; j < list.length; j++) {
var c = list[j];
var lan = convertIsoCode(c.IsoCode);
var fileName = array[i].Name + "_" + lan;
var country = array[i].Country;
doAll(c,lan,country,fileName, function(){
newArray.push(array[i]);
if (array.length == newArray.length) {
console.log('done');
defer.resolve('done');
}
})
}
}
EDIT:
Я пытался сделать это с async.each
и async.parallel
, но не удалось, может ли кто-нибудь показать мне правильный способ его реализовать?
Я мало знаю о обещаниях, но кажется, что 'Promise.all' - это то, что вы ищете. ['async.each'] (http://caolan.github.io/async/docs.html#.each) также будет делать то, что вам нужно. – DrakaSAN
async.each от того, что я понимаю, это каждая функция, поэтому вы можете делать несколько функций в одном и том же тиме, но здесь также нужно делать некоторые из них за каждый элемент и ждать, пока все закончится и обещают все? не уверен, что мне нужно ждать до следующего – Erez
'async.each' поддерживает обратный вызов, который будет вызываться после завершения каждой функции или если в любой из функций передается ошибка. Кроме того, вы можете уведомить кого-то, когда вы ответите ему, используя @DrakaSAN, я только видел ваш пост на удачу. – DrakaSAN