2016-10-04 5 views
4

私はこの問題をはっきりと記述することができないことを申し訳ありません。私は試してみる:1つの非同期関数をグループで呼び出すにはどうすればよいですか?

今私はデータを取って何かを行う非同期関数がある。

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

このtypescriptですか?その場合は、タグ – evolutionxbox

+2

を追加して、一度にmyFunctionを5回だけ呼び出すようにしてから、Promise.allを使用して5の各セットを待ってください。ただし、これはタイプスクリプトなので、全く異なる方法があります。 –

+1

おそらくTypescriptではないかもしれませんが、流れになる可能性があります:) – 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

私は発電機を使用する、またはあなたはtypescriptですを使用しているので、あなたは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もちろん、非同期/待機(奇妙なことは禁じられています)なしでもやることができます。約束や普通のコールバックを選択することもできますが、コードは単純ではありません。 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); 
    } 
}()); 
関連する問題