2017-08-03 5 views
0

私はほとんど肯定的ですが、これについての説明が必要ですが、 ary.filter()を使用して配列を変換しようとしたときに私の非同期コードが早く解決するように見える理由を理解しようとしましたが、ary.map()を使用すると、このトピックについていくつかの光を当てるのを助けることができる誰もが大歓迎です!async/await:Array.prototype.mapを使用した非同期配列変換(動作)vs Array.prototype.filter(動作しない)

わかりやすくするために、ノード8.2.1も使用しています。

したがって、問題を説明するためのコードと出力を提供するには、を使用してになり、コンソールに次の出力を提供する例を示します。

(async() => { 
    const timeStart = Date.now() 
    const ary = new Array(20).fill(0).map((v, i) => i+1) 

    const newAry = await Promise.all(
    ary.map(async val => { 
     return await new Promise((resolve, reject) => { 
     setTimeout(() => resolve(val*2), 1000) 
     }) 
    }) 
) 
    console.log('original ary', ary) 
    console.log('newAry is', newAry) 
    const timeEnd = Date.now() 
    console.log(timeEnd - timeStart, 'milliseconds between start and end') 
})() 

次のようにコンソールに出力されている:

original ary [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ] 
newAry is [ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40 ] 
1022 milliseconds between start and end 

あなたが期待するように、元の配列が変換され、そして期待通り出力されたときの間〜1秒があります。

次のコードは非常によく似ていますが、ary.filter()を使用し、ではなく、が期待通りに戻ります。次のように

(async() => { 
    const timeStart = Date.now() 
    const ary = new Array(20).fill(0).map((v, i) => i+1) 

    const newAry = await Promise.all(
    ary.filter(async val => { 
     return await new Promise((resolve, reject) => { 
     setTimeout(() => resolve(Math.random() < 0.5), 1000) 
     }) 
    }) 
) 
    console.log('original ary', ary) 
    console.log('newAry is', newAry) 
    const timeEnd = Date.now() 
    console.log(timeEnd - timeStart, 'milliseconds between start and end') 
})() 

出力は、次のとおり/待つ非同期を使用する場合

original ary [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ] 
newAry is [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ] 
18 milliseconds between start and end 

なぜary.filter()を適切な時間に配列を変換し、解決の点でary.map()と同様に動作しないのですか?

+0

投稿をすべて読んでください。必要に応じて、アクセス権を持っているマシン上でコードをローカルに実行して、動作を確認してください。 –

答えて

2

Promise.all()を呼び出すことは、約束の配列にのみ意味があります。

.map()は、そのコールバックの結果を返します。コールバックがasyncの場合、これは約束です。したがって、それはうまく動作します。

.filter()は、そのコールバックの結果をブール値として扱います(ブール値ではありません)。次に元の配列の項目を返します。

+0

ああありがとう、私はそれを得ると思うが、私の例では '.filter()'に約束しているので、これは本当に真実で、私は元の配列のすべての要素を取得するだろう。私は、可能な場合はネイティブな約束事を使用しようとしているかのように、ブルーバードに存在していると思われるユーティリティ以外の解決策がないと仮定しています。または、何らかの形でtrue/falseを返すために.mapを使用するコードを追加しますその配列をフィルタリングしますか? –

+0

@LanceWhatley:正しい。 – SLaks

+0

もう一度おねがいします。十分な時間がなかったので、まだ回答を受け入れることはできませんが、まもなく受け入れます。 –

関連する問題