2017-09-25 2 views
3

내가 다른 인수 함수 호출 3 회를 만드는 중이라서 :for each 루프 for async code?

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 호출을해야하므로 처음 세 호출. 내 코드를 건조하기 위해 나는 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 

어떻게 작동합니까?

보너스 : 키 - 값 쌍을 각 개체에 어떻게 할당합니까?

+3

가능한 (우리는 정말로 필요 await.all concept 그래서 위의 혼합되지는 은유 ... 그) [* 콜백 내에서 올바른 '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

Stack Snippets ([[>] 도구 모음 단추)는 ** 실행 가능한 ** 코드. 코드 블럭의 경우,'{}'버튼 (또는 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 기능에 두 개의 버그가 있습니다 :

  1. 그것은 async 기능은 당신이, await 약속을 자동 -하지 (반환하기 전에 완료 axios.get 기다리지 않습니다 명시 적으로)

  2. 반환 된 약속의 거부를 처리하지 않습니다. axios.get

this.addLinkToContributor 번으로 전화를 3 번 ​​반복하는 것이 정확하고 두 번째 두 번 낭비가 될지 궁금합니다.코멘트에서

님의 요청했습니다 :

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'} 
]); 

+0

'결과 '는 하나의 속성 만 변경된 동일한 객체 (제공자)의 3 개 배열입니다. 그래서 하나의 배열은 요지를 가진 기여자를, 다른 것은 추종자를 가지고 있습니다. 이제 어떻게 든 그것들을 연결 시키거나'getContributorProperties' 함수에서 그렇게하는 것이 더 낫습니다. –

+1

@AdamMarczyk : 답변에 추가했습니다. 그 내용과 몇 가지 사항을 설명했습니다. –

+0

첫 번째 버그를 해결합니까? '비동기 contributorsLoop 함수() {위한 (하자 I = 0; I <10은, I + = 1) { }} CONST 입술 = contributorsLoop가 기다리고(); return res; }' –