2017-12-10 7 views
0

저는이 프레임 워크를 사용하여 큰 프로젝트에서 5 년 및 2 년 동안 Node.js로 작업하고 있습니다. 2 년 동안 MySQL, MongoDB 또는 Apache SolR과 같은 스택 요청 인 비동기식 타사 응용 프로그램과 비동기식으로 빠르게 작업하는 방법에 대한 문제에 직면했습니다.Node.js : 느린 타사와 작업하십시오

const promises = [] 

for (let i = 0; i < 1000; i += 1) { 
    const promise = mySqlRequest() 
    promises.push(promise) 
} 

Promise.all(promises) 
.then() 
.catch() 

이 예제는 작동하지만 이러한 스택 것입니다 MySQL 서버에 동시에 1,000 요청을 보내드립니다 :

나는 다음과 같이 약속하고 준비 몇 가지 약속 요청에 일을 사용 해요 요청이 매우 느리게되고, 대량의 RAM을 소비하게됩니다.

가장 좋은 해결책은 하나의 큰 요청 만하는 것이지만 어떤 경우에는 불가능하며 재귀 적 기능 인 을 사용해야 만 동기가 느려지고 느려집니다.

Node.js 및 스태킹 타사와 빠르고 비동기로 작업하는 가장 좋은 방법은 무엇입니까?

답변

1

한 번에 모든 요청을 보내지 않아도 작동하지 않고 하나씩 보내지도 않으면 임의의 수의 작업이 동시에 실행되는 스레드 풀과 비슷한 것이 필요합니다. 이 같은 예를 들어, 약속을 사용하여 쉽게 구현 가능하다 : 이것은 당신을 허용 무엇

Promise.pooled = function(arr, num = 5) { 
    return new Promise(function(resolve, reject) { 
     var i = -1; 
     var error = false; 

     var end = function() { 
      num--; 
      if(num === 0) resolve(); 
     } 

     var next = function() { 
      if(error) return; 
      i++; 
      if(i >= arr.length) 
       end(); 
      else 
       arr[i]().then(next).catch(onerr); 
     } 

     var onerr = function() { 
      if(error) return 
      error = true 
      reject.call(arguments) 
     } 

     for(var j = 0; j < num; j++) 
      next() 
    }); 
} 

는 그 기능이 더 매개 변수를 사용하지 않고 약속을 반환해야합니다 첫 번째 인수로 기능의 배열 을 전달합니다. 그러면 정확히 num이 동시에 실행됩니다. 약속 중 하나라도 실패하면 약속도 지키지 않고 실행을 중단합니다 (쉽게 변경할 수 있음).

예 :

Promise.after = function(ms) { 
 
    return new Promise(function(resolve) { 
 
     setTimeout(resolve, ms) 
 
    }); 
 
} 
 

 
Promise.pooled = function(arr, num = 5) { 
 
\t return new Promise(function(resolve, reject) { 
 
\t \t var i = -1; 
 
\t \t var error = false; 
 
\t \t 
 
\t \t var end = function() { 
 
\t \t \t num--; 
 
\t \t \t if(num === 0) resolve(); 
 
\t \t } 
 
\t \t 
 
\t \t var next = function() { 
 
\t \t \t if(error) return; 
 
\t \t \t i++; 
 
\t \t \t if(i >= arr.length) 
 
\t \t \t \t end(); 
 
\t \t \t else 
 
\t \t \t \t arr[i]().then(next).catch(onerr); 
 
\t \t } 
 
\t \t 
 
\t \t var onerr = function() { 
 
\t \t \t if(error) return 
 
\t \t \t error = true 
 
\t \t \t reject.call(arguments) 
 
\t \t } 
 
\t \t 
 
\t \t for(var j = 0; j < num; j++) 
 
\t \t \t next() 
 
\t }); 
 
} 
 

 
var test = [ 
 
\t afterH(1000), 
 
\t afterH(500), 
 
\t afterH(800), 
 
\t afterH(600), 
 
\t afterH(3000), 
 
\t afterH(300), 
 
\t afterH(900), 
 
\t afterH(2000), 
 
\t afterH(1500), 
 
\t afterH(900), 
 
\t afterH(700), 
 
\t afterH(600), 
 
\t afterH(700) 
 
]; 
 

 
// helper function, returns a function which when invoked returns a promise 
 
function afterH(ms) { 
 
\t return function() { 
 
\t \t console.log("Starting one job") 
 
\t \t return Promise.after(ms); 
 
\t } 
 
} 
 

 
Promise.pooled(test, 3).then(function() {console.log("All jobs finished") }).catch(function() {console.log("Job failed")})