>
var promiseReturningFuncs = [];
for(var i = 0; i < 5; i++){
  promiseReturningFuncs.push(askQuestion);
}
var programmers = [];
Promise.reduce(promiseReturningFuncs, function(resp, x) {
  console.log(typeof resp);
  if(typeof resp != "function") {
    programmers.push(resp);
  }
  return x();
})
.then(function(resp) {
  programmers.push(resp);
  console.log(programmers);
});

내 목표 : askQuestion 함수를 직렬로 실행하고 해당 함수로 생성 된 객체 배열을 확인합니다. (이 기능은 사용자 입력에 응답 할 수 있도록 직렬로 실행되어야합니다)

as askQuestion 함수가 배열에 추가하려는 객체를 해결하는 약속을 반환한다고 상상해보십시오.

이것은 내 지저분한 방법입니다. 더 깨끗한 방법을 찾고 싶습니다. 이상적으로는 배열로 푸시 할 필요조차 없습니다. 최종. 그러면 응답이 배열입니다.


  • 답변 # 1

    Bluebird promise 라이브러리를 사용하고있는 것처럼 보이기 때문에 promise 반환 함수를 시퀀싱하기위한 여러 가지 기본 제공 옵션이 있습니다. Promise.reduce() 를 사용할 수 있습니다 Promise.map()  동시성 값이 1 인 Promise.mapSeries  또는 Promise.each() . 반복자 함수가 약속을 반환하면 약속이 해결 될 때까지 다음 반복을 기다립니다. 어떤 것을 사용할 것인지는 데이터의 구조와 원하는 결과 (실제로 표시하거나 설명하지 않은)의 메커니즘에 따라 다릅니다.

    약속 반환 함수 배열이 있고 한 번에 하나씩 호출하여 다음 함수를 호출하기 전에 함수가 해결되기를 기다리는 경우를 가정 해 봅시다. 모든 결과를 원한다면 Promise.mapSeries() 를 제안합니다. :

    let arrayOfPromiseReturningFunctions = [...];
    // call all the promise returning functions in the array, one at a time
    // wait for one to resolve before calling the next
    Promise.mapSeries(arrayOfPromiseReturningFunctions, function(fn) {
        return fn();
    }).then(function(results) {
         // results is an array of resolved results from all the promises
    }).catch(function(err) {
         // process error here
    });
    
    

    Promise.reduce()  또한 사용될 수 있지만 단일 결과를 누적하여 하나에서 다음으로 전달하고 하나의 최종 결과로 끝납니다 ( Array.prototype.reduce() 와 같은)  ).

    Promise.map()   Promise.mapSeries() 의 더 일반적인 버전입니다  이를 통해 동시성 수 (동기 비행 중 비동기 작업 수)를 제어 할 수 있습니다.

    Promise.each()  함수를 시퀀싱하지만 결과를 누적하지는 않습니다. 결과가 없거나 대역 외 또는 부작용을 통해 결과를 누적한다고 가정합니다. 나는 Promise.each() 를 사용하지 않는 경향이 있습니다  부작용 프로그래밍이 마음에 들지 않기 때문입니다.

  • 답변 # 2

    ES6 (ES2015) 기능을 사용하여 순수 JS에서이 문제를 해결할 수 있습니다.

    function processArray(arr, fn) {
        return arr.reduce(
            (p, v) => p.then((a) => fn(v).then(r => a.concat([r]))),
            Promise.resolve([])
        );
    }
    
    

    일련의배열에 지정된 기능을 적용하고결과 배열로 해석됩니다.

    사용법 :

    const numbers = [0, 4, 20, 100];
    const multiplyBy3 = (x) => new Promise(res => res(x * 3));
    // Prints [ 0, 12, 60, 300 ]
    processArray(numbers, multiplyBy3).then(console.log);
    
    

    브라우저 호환성을 다시 확인하고 싶지만 현재 Chrome (v59), NodeJS (v8.1.2) 및 아마도 대부분의 다른 기기에서 작동합니다.

  • 답변 # 3

    재귀를 사용하여 then 에서 다음 반복으로 이동  차단합니다.

    function promiseToExecuteAllInOrder(promiseReturningFunctions /* array of functions */) {
      var resolvedValues = [];
      return new Promise(function(resolve, reject) {
        function executeNextFunction() {
          var nextFunction = promiseReturningFunctions.pop();
          if(nextFunction) {
            nextFunction().then(function(result) {
              resolvedValues.push(result);
              executeNextFunction();
            });
          } else {
            resolve(resolvedValues);
          }
        }
        executeNextFunction();
      }
    }
    
    

  • 답변 # 4

    재귀 함수를 사용하여 (비 약속 방식으로) 차례로 실행 :

    (function iterate(i,result,callback){
     if( i>5 ) callback(result);askQuestion().then(res=>iterate(i+1,result.concat([res]),callback);
    })(0,[],console.log);
    
    

    슈어를 위해 이것은 약속에 싸여 질 수있다 :

    function askFive(){
    return new Promise(function(callback){
    (function iterate(i,result){
     if( i>5 ) callback(result);askQuestion().then(res=>iterate(i+1,result.concat([res]),callback);
    })(0,[],console.log);
    });
    }
    askFive().then(console.log);
    
    

    또는 :

    function afteranother(i,promise){
       return new Promise(function(resolve){
         if(!i) return resolve([]);
         afteranother(i-1,promise).then(val=>promise().then(val2=>resolve(val.concat([val2])));
       });
    }
    afteranother(5,askQuestion).then(console.log);
    
    

  • 이전 플랫 JSON에서 HTML로 데이터 검색
  • 다음 JavaScript로 기존 FileList 객체에 추가하는 방법은 무엇입니까?