2017-09-25 12 views
3

私は別の引数を持つ関数呼び出しを3回作っています:for eachループfor非同期コード?

this.getContributorProperties('followers_url', 'contributorFollowers'); 
this.getContributorProperties('gists_url', 'contributorGists'); 
this.getContributorProperties('repos_url', 'contributorRepositories'); 

この関数は以下のようになります。

async getContributorProperties(propertyUrl, propertyName) { 
    const contributors = await this.addLinkToContributor(); 
    for (let i = 0; i < 10; i += 1) { 
     axios.get(`${contributors[i][propertyUrl]}?per_page=100&${API_KEY}`).then((res) => { 
     contributors[i][propertyName] = res.data.length; 
     }); 
    } 
    return contributors; 
} 

それは貢献者の配列(オブジェクトタイプ)をループし、APIコールを行いますそれらのそれぞれのために。私は3つのAPIコールをそれぞれ1つずつ作成する必要があるため、最初は3つの呼び出しを行います。私はそうのようなforeachループを作りたかった私のコードまで乾燥させるために :私はそれがうまく動作3つの呼び出しを行うとき

[ 
     ['followers_url', 'contributorFollowers'], 
     ['gists_url', 'contributorGists'], 
     ['repos_url', 'contributorRepositories'], 
    ].forEach(this.getContributorProperties); 

foreachループはcomponentDidMount() です。しかし、私がするときは、エラーが発生します:

Uncaught (in promise) TypeError: Cannot read property 'addLinkToContributor' of undefined 

どうすればいいですか?

BONUS:これらのキーと値のペアを各オブジェクトに割り当てるにはどうすればよいですか?

+3

ような何か[*コールバックの中で正しい 'this 'にアクセスするには?*](http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback )および/または[*どのように"this"キーワードは動作しますか?*](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) –

+1

スタックスニペット( '[<] 'ツールバーボタン)は**実行可能コード**。単なるコードブロックの場合、 '{}'ボタン(またはCtrl + Kか、各行に4つのスペースをインデントする)を使用します。 –

答えて

6

具体的なエラーメッセージが表示された理由は、How to access the correct this inside a callback?および/またはHow does the "this" keyword work?を参照してください。

しかし、基本的には、forEachにその機能を渡すだけではなく、forEachがその機能を必要とするものに渡すことはありません。

代わり

、ちょうど矢印の機能を使用します。

[ 
    ['followers_url', 'contributorFollowers'], 
    ['gists_url', 'contributorGists'], 
    ['repos_url', 'contributorRepositories'], 
].forEach(pair => this.getContributorProperties(pair[0], pair[1]).catch(err => {/*...handle error...*/}); 

注エラー処理を、 forEachは未処理の拒否を望んでおらず、発信者に伝播するために何もしません。


戻り値は何も使用しないでください。おそらくmapPromise.all

const results = await Promise.all([ 
    ['followers_url', 'contributorFollowers'], 
    ['gists_url', 'contributorGists'], 
    ['repos_url', 'contributorRepositories'], 
].map(pair => this.getContributorProperties(pair[0], pair[1]))); 

...、発信者がない場合はエラーを処理するようにしてくださいという。


あなたgetContributorProperties関数内の2つのバグがありますのでご注意ください。

  1. それはasync機能は、あなたが持っている、await約束を自動していない(返す前に完了するのaxios.getを待ちません。

  2. 返される約束の拒否を処理しないaxios.get

this.addLinkToContributorへの呼び出しが3回繰り返されていて、2回目の2回が無駄かもしれないかどうかは興味があります。

Results are 3 arrays of the same objects (contributors) with just one property changed each. So one array has contributors with gists, another with followers, etc. Do I now somehow concatenate them or is it better to do that in getContributorProperties function?

私の本能のようになります。あなたが求めてきましたコメントで

、このように呼ばれる
async getContributorProperties(properties) { 
    const contributors = await this.addLinkToContributor(); 
    return Promise.all(contributors.map(contributor => 
     Promise.all(properties.map(property => 
     axios.get(`${contributor[property.url]}?per_page=100&${API_KEY}`).then(res => { 
      contributor[property.name] = res.data.length; 
     }) 
    )); 
    )); 
} 

const results = await this.getContributorProperties([ 
    {url: 'followers_url', name: 'contributorFollowers'}, 
    {url: 'gists_url',  name: 'contributorGists'}, 
    {url: 'repos_url',  name: 'contributorRepositories'} 
]); 

(上記はその比喩を混合しないように、私たちは本当にawait.all conceptことを必要とする...)可能

+0

'結果 'は、1つのプロパティだけが変更された同じオブジェクト(コントリビュータ)の3つの配列です。だから、1つの配列には要点があり、もう1つの配列にはフォロワーなどがあります。どうやらそれらを連結したり、 'getContributorProperties'関数でそれを行うほうがいいですか? –

+1

@AdamMarczyk:私は答えに加えて、それと他のいくつかのことに取り組んだ。 –

+0

最初のバグに対処していますか? '非同期関数contributorsLoop(){ため (LET i = 0; iは<10、I + = 1){ }} CONST RESの=はcontributorsLoopを待ちます()。 return res; } ' –

関連する問題