2016-09-03 4 views
1

で待つ:私は非同期を使用するようにリファクタリングしたい非同期は、私が期待どおりに動作、次の機能を持っているのforEach

createObjectFrom(record) { 
    let obj = {}; 

    this.opts.transformers.forEach((transformer, index) => { 
     const headerIndex = findIndex(this.headers, (header) => { 
     return header === transformer.column; 
     }); 

     const value = transformer.formatter(record[headerIndex]); 

     obj[transformer.field] = value; 
    }); 

    return obj; 
    } 

が待っていますし、このようにforEachののボディに非同期関数を呼び出す:

createObjectFrom(record) { 
    let obj = {}; 

    this.opts.transformers.forEach(async (transformer, index) => { 
     const headerIndex = findIndex(this.headers, (header) => { 
     return header === transformer.column; 
     }); 

     const result = await this.knex('managers').select('name') 

     console.log(result); 

     const value = transformer.formatter(record[headerIndex]); 

     obj[transformer.field] = value; 
    }); 

    return obj; 
    } 

これは明らかにforEachが非同期に実行され、関数が実行して終了するため、関数を破壊することになります。

forEachが同期的に実行されるように、非同期的に使用できる方法はありますか。私は発電機にリファクタリングすることができますか?

+0

"forEachが現在非同期で実行されているため、これは明らかに関数を破壊します" ---何も変更されません。 'Array.prototype.forEach'は' async'関数を受け入れることを期待していないので、それを "普通の"関数として呼び出すでしょう。したがって、すべての関数はすぐに呼び出されます。 – zerkms

+0

"forEachが同期的に実行するために非同期で使用できる方法はありますか?---単にforまたはfor-of'ループを使用して配列を反復処理します。また、 'createObjectFrom'を' async'に変更する必要があります。 – zerkms

+0

[この1つ](https://github.com/toniov/p-iteration)を使ってこのようなことをスムーズに行うことができます。モジュールを気にする必要がなければ試してみてください。 –

答えて

1

非同期動作を待機する通常のJS関数を強制することはできません。道はない!

したがって、createObjectFromを非同期にリファクタリングする必要があります。そして、おそらくforEachの代わりにmap/reduceを使うべきでしょう。

for(transformer of this.opts.transformers) { 
    await this.knex('managers').select('name'); 
} 

代わりにあなたがawait Promise.all(...)を使用する必要があります。 は、あなたがこれを行うにはしたくないパフォーマンスであるために。あなたは非同期各項目の何かのためにフェッチのようにそれを行うような何かをしたい場合は

async createObjectFrom(record) { 
    let obj = {}; 

    const result = await this.knex('managers').select('name') 

    this.opts.transformers.forEach(async (transformer, index) => { 
    const headerIndex = findIndex(this.headers, (header) => { 
     return header === transformer.column; 
    }); 

    console.log(result); 

    const value = transformer.formatter(record[headerIndex]); 

    obj[transformer.field] = value; 
    }); 

    return obj; 
} 

:あなたがこれを行うことができますので

は、しかし、あなたのケースでknexへの呼び出しは、変圧器に依存していないようです

async foo(data) { 
    const subDataArr = await Promise.all(data.map(record => loadSubData(record))); 

    return subDataArr; 
} 
+0

私はforeachの各繰り返しに対してknexコールを必要とします。私はこのノードでどのように扱われているのか不思議です。普通の使用例です。 – dagda1

+0

@ dagda1 thats基本的に私の最後のコード例です。 'loadSubData'がKnex呼び出しであると仮定します。 – Lux

関連する問題