2016-10-04 2 views
4

이 문제를 명확하게 설명하지 못해 죄송합니다. 나는 시도 할 것이다 :하나의 비동기 함수를 그룹 방식으로 호출하려면 어떻게해야합니까?

나는 데이터를 취하고 무언가를하는 비동기 함수 하나를 가지고있다.

function myFunction(num: number):Promise<void> { 
    return new Promise((resolve) => { 
    console.log(num); 
    return; 
    }); 
} 

그룹에 5 개의 숫자를 인쇄하고 싶습니다 (순서는 중요하지 않음). 중요한 것은 이전 그룹이 끝난 후 다음 5 자리 숫자를 인쇄하고 싶다는 것입니다.

1, 2, 5, 4, 3, 6, 9, 8, 7, 10 ... is valid 
7, 10, 1, 2, 3, 4, 5, 6, 8, 9 ... is not valid 

어떻게 내가이 기능을 사용하는 경우이 그렇게 할 수 있습니다 : 예를 들어 ? 이 함수의 처음 5 개 호출이 해결되었는지 확인한 후 다음 5 개 함수 호출을 시작해야합니다. 이게 이상한 것처럼 보입니다. 저는 현재 문제를이 번호 문제로 추상화하려고합니다.

의견이나 아이디어에 감사드립니다.

+0

이 타이프 라이터인가? 그렇다면 – evolutionxbox

+2

태그를 추가해야합니다. 한 번에 myFunction을 5 번만 호출해야합니다. 그런 다음 Promise.all을 사용하여 각 5 세트를 기다리십시오. 그러나이 태그는 완전히 다른 방법 일 수 있습니다. –

+1

글쎄요. Typescript가 아닐지도 모르지만 .. Flow가 될 수 있습니다 :) – Keith

답변

4

어레이를 청크로 분할하고 Array#mapPromise#all을 사용하여 청크를 처리하면이 작업을 수행 할 수 있습니다. 그런 다음 문자열 함께 Array#reduce를 사용하여 청크 처리 할 수 ​​있습니다

runChunkSeries([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5, someAsyncFn); 

// our placeholder asynchronous function 
function someAsyncFn(value) { 
    return new Promise((resolve) => { 
    setTimeout(resolve, Math.random() * 5000); 
    }).then(() => console.log(value)); 
} 

function runChunkSeries(arr, chunkSize, fn) { 
    return runSeries(chunk(arr, chunkSize), (chunk) => Promise.all(chunk.map(fn))); 
} 

// Run fn on each element of arr asynchronously but in series 
function runSeries(arr, fn) { 
    return arr.reduce((promise, value) => { 
    return promise.then(() => fn(value)); 
    }, Promise.resolve()); 
} 

// Creates an array of elements split into groups the length of chunkSize 
function chunk(arr, chunkSize) { 
    const chunks = []; 
    const {length} = arr; 
    const chunkCount = Math.ceil(length/chunkSize); 

    for(let i = 0; i < chunkCount; i++) { 
    chunks.push(arr.slice(i * chunkSize, (i + 1) * chunkSize)); 
    } 

    return chunks; 
} 
여기

의는 codepen 작업.

1

내가 발전기을 사용하거나, 타이프 라이터를 사용하고 있기 때문에, 당신은 ES7 비동기/await를 구문 및 lodash이 같은 뭔가를 할 수 사용하여 사용할 수 있습니다

(async function(){ 
    const iterations: number = 2; 
    const batchSize: number = 5; 
    let tracker: number = 0; 
    _.times(iterations, async function(){ 
    // We execute the fn 5 times and create an array with all the promises 
    tasks: Promise[] = _.times(batchSize).map((n)=> myFunction(n + 1 + tracker)) 
    await tasks // Then we wait for all those promises to resolve 
    tracker += batchSize; 
    }) 
})() 

당신은/잠시와 lodash을 대체 할 수 원하면 루프. 내가 제대로 이해하지 못하거나 코드에 문제가있을 경우

확인 https://blogs.msdn.microsoft.com/typescript/2015/11/03/what-about-asyncawait/

알려주세요 그리고 난 대답을 업데이 트됩니다.

+0

답장을 보내 주셔서 감사합니다 @ Zagen! 나는 이것을 위해'async' 또는'await'을 사용하지 않는 방법이 있는지 궁금합니다. 현재 개발 중에있는 규칙은 이러한 규칙을 사용하는 것을 허용하지 않습니다. Promise.all()을 사용할 수는 있지만이 코드를 작성하는 방법을 모르겠습니다. – Lubor

+0

@ Lubor, 물론 당신은 async/await (금지하는 이상한 일)없이 그것을 할 수 있습니다, 당신은 약속이나 심지어 콜백을 선택할 수 있지만 코드는 간단하지 않습니다. SimpleJ 응답을 확인하십시오. 좋은 구현이며 약속 만 사용합니다. – Zagen

1

그것은 async/await 실제로 사용 아주 간단 :

(async function() { 
    var i = 0; 
    while (true) { 
     for (var promises = []; promises.length < 5;) { 
      promises.push(myFunction(i++)); 
     } 
     await Promise.all(promises); 
    } 
}()); 
관련 문제