2016-08-29 2 views
-1

파일을 비동기 적으로 업로드하는 방법을 구현하려고합니다. 배열의 모든 항목에 적용 할 프로세스가 있습니다. 각 항목의 이름을 가져 와서 API를 호출하여 추가 정보를 얻은 다음 텍스트를 음성 유틸리티로 보내고 wav 파일을 S3 인스턴스에 업로드합니다.노드 js - 배열의 각 항목에 대한 멀티 태스킹

이 작업을 비동기 적으로 수행하고 모든 작업을 마칠 때까지 기다릴 수 없습니다.

나는 세리에로 할 수는 있지만 시간이 많이 걸린다. (30 개 파일 당 12 분 (각 파일 당 2MB)).

약 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'); 
      } 
     }) 
    } 

} 

편집 :

async.eachasync.parallel으로 해보려고했지만 성공하지 못했습니다. 누구든지 올바른 방법으로 구현할 수 있습니까?

+0

저는 약속에 대해 많이 알지 못하지만, 'Promise.all'이 당신이 찾고있는 것 같습니다. ['async.each'] (http://caolan.github.io/async/docs.html#.each) 또한 필요한 것을 할 것입니다. – DrakaSAN

+0

async.each는 각 기능을 이해하므로 같은 시간에 몇 가지 기능을 수행 할 수 있지만 여기에도 각 항목에 대해 동시에 일부 작업을 수행하고 모든 작업을 완료하고 모두 약속하겠습니까? 확실하지 않기 때문에 다음에 기다릴 필요가 없습니다. – Erez

+0

'async.each'는 모든 함수가 끝나면 호출되거나 어떤 함수에서 콜백에 오류가 전달되는지를 콜백을 지원합니다. @DrakaSAN을 사용하여 그에게 대답 할 때 누군가에게 알릴 수 있습니다. 나는 행운을 빌어서 만 귀하의 게시물을 보았습니다. – DrakaSAN

답변

1

아무 도움이 필요 없기 때문에 newArray이 삭제되었으므로 CPU 시간이 낭비되었으며 완료된 작업을 추적하는 끔찍한 방법이었습니다. 간단한 카운터가 트릭을했을 것입니다.

2016 년 이래로 ES6이 사라졌습니다. 세미 콜론이 추가되었습니다.

또한 doAll은 의미있는 이름이 아닙니다.

'use strict'; 

const async = require('async'); 

let array = [/*data*/]; 

console.log('START ' + (new Date())); 
//Asynchronously iterate throught the array 
async.each(array, (item, callback) => { 
    //item is your array[i] 
    async.each(item.Langs, (lang, callback) => { 
     //lang is your array[i].Langs[j] 
     let lan = convertIsoCode(item.IsoCode), 
      fileName = item.Name + '_' + lan, 
      country = item.Country; 

     //Apply your functions 
     getNews(c, lan).then((newsResults) => { 
      getWavFile(newsResults, lan, fileName).then((wavResults) => { 
       uploadToS3(country,lan,fileName).then((s3Results) => { 
        //Everything is OK, callback without error 
        callback(); 
       }, (s3err) => { 
        //Raise the error 
        callback(s3err); 
       }); 
      }, (waverr) => { 
       console.log('wav error: ',waverr); 
       //Raise the error 
       callback(waverr); 
      }); 
     }, (newserr) => { 
      console.log('news error: ',newserr); 
      //Raise the error 
      callback(newserr); 
     }); 
    }, (error) => { 
     callback(error); 
    }); 
}, (error) => { 
    //If a error was raised, everything pending will be aborted and the error will be displayed 
    if(error) { 
     console.log(error); 
    //Else, just report it did fine 
    } else { 
     console.log('OK'); 
    } 
}); 
+0

마술 같이 일하십시오! 감사합니다 – Erez

+0

나는 ES5에서 코드를 다시 작성하거나 ES6에서 코드의 나머지 부분을 다시 작성하고 'eslint'와 같은 도구를 사용하여 일관된 스타일을 유지하도록 조언합니다. 그러면 자신을 향상시키고 도움을받을 수 있습니다. 코드 개월 래터를 다시 방문하십시오. – DrakaSAN

+0

감사합니다. 대단히 감사합니다. – Erez