2017-09-13 2 views
1

함께 해결해야하는 약속 그룹 작업 방법을 이해하는 데 어려움이 있습니다.약속 그룹과 함께 작업

필자의 상황에서는 ID 배열을 기반으로 일련의 약속 호출을 만들고 출력 배열에 선택적으로 추가하려고합니다.

$output = [] 
foreach($input as $id) { 

    $result1 = functioncall1($id); 
    $result2 = functioncall2($result1); 

    if ($result2 == 'some filter') { 
    $output[] = $result1; 
    } 
} 

이 루프가 반환하는 결과를 기다리지 않는 비동기 호출을 수행 할 수 없습니다 :이 PHP라면 내가 좋아하는 일을 할 것입니다. 그래서 나는이 같은 블루 버드 약속을 사용하고 있습니다 :

Promise.map(input, function(id) { 
    promisifedFunction1(id) 
     .then(function(result1) { 
      //process result1 some more 

      promisifedFunction2(result1) 
      .then(function(result2) { 
       //process result2 some more 

       if (result2 == 'some filter') { 
        return result1; 
       }); 

      }); 

     }) 
    .then(function(output) {}); 
} 

을 내 출력은 오직 정의의 배열을 포함하고 있기 때문에 내가 분명히 여기에 뭔가를 놓친 거지. 그러나 그것은 분명히 매핑 및 마지막에 도달하면 내가 기대하고 정의되지 않은 배열은 때만 그것을 필터링 oks 때 생산됩니다. 필터가 리터럴 문자열을 반환하는 경우에도 undefined가 생성됩니다.

나는 뭔가를 놓치고 있지만 나는 틈을 메꾸기 위해 고심하고있다.

+0

'Promise.all' ... https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all –

답변

1

나는 이미 여기에 답이 있다고 가정했으나 분명히 그렇지 않습니다 (또는 빠른 검색을하지 않으면 찾지 못했습니다). 당신은 (그것을 약속의 배열을 제공의 배열에 당신의 약속을 돌려주는 기능을 매핑하여 :

let filteredResults = Promise.all(arr.map(x => promisifiedFn1(x))) 
    .then(xs => xs.map(result1 => promisifiedFn2(result1))) 
    .then(ys => ys.filter(someFilteringFn)); 

Promise.all 내부 아웃 용기를 회전으로 간주 할 수 있습니다 :

는이 같은 구조를 원하는 입력), 다른 배열과 마찬가지로 처리 할 결과 배열을 약속합니다.

따라서 xs은 모두 해결 된 입력을 통해 매핑 된 첫 번째 기능 결과의 배열입니다. ys이 두 번째입니다. 나는 bluebird의 Promise.map이 무엇인지는 모르겠지만 아마도 내 코드에서 처음 두 단계를 결합 할 수 있습니다.

결과를 유지할지 여부를 결정하기 전에 각 입력을 완전히 처리해야하기 때문에 두 비동기 단계로 입력을 처리하고 모든 결과가 해결되면 결과 배열을 필터링하는 데 아무런 형벌이 없습니다.

1

당신의 promisified 기능을 확인 있는지 확인,이 또한 작동합니다 :

var elements = ["one", "two", "three"] 
 
var container = document.querySelector('.results') 
 

 
function promisifiedFunc1(arrayElement) { 
 
    return new Promise(function(resolve, reject) { 
 
    setTimeout(function() { 
 
     resolve('input to the next func ' + arrayElement) 
 
    }, 1000) 
 
    }) 
 
} 
 

 
function promisifiedFunc2(inputFromPreviousFunc) { 
 
    return new Promise(function(resolve, reject) { 
 
    container.innerHTML += "<br>" + inputFromPreviousFunc 
 
    setTimeout(function() { 
 
     resolve('some filter') 
 
    }, 1000) 
 
    }) 
 

 
} 
 

 
Promise.map(elements, function(one) { 
 
    return promisifiedFunc1(one).then(promisifiedFunc2); 
 
    }) 
 
    .filter(function(res2) { 
 
    return res2 === 'some filter'; 
 
    }) 
 
    .then(function(allResults) { 
 
    console.log(allResults); 
 
    container.innerHTML += "<br>All Done!"; 
 
    })
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.5.0/bluebird.min.js"></script> 
 
<div class="results"></div>

Promise.map 당신이 약속의 배열에 어떤 배열을지도하고있는 새로운 약속을 생성 할 수 있습니다 이러한 모든 약속이 해결되면 해결되어야합니다. 매핑 기능 내에서 두 가지 약속을 연결할 수 있습니다. 당신은 그 코드를 만들기 위해 ETA-감소 할 수

0

많이 간단 찾습니다

Promise.map(input, promisifedFunction1) 
     .map(promisifiedFunction2) 
     .filter(v => v === 'someFilter') 
     .then(outputFunction); 
관련 문제