2017-03-01 16 views
0

配列全体を反復処理して各アイテムのREST API呼び出しを行いますが、jsの非同期性に問題があります。私はasync/awaitを使用しようとしていますが、私は応答を待つことなく未定義を返すので正しく設定しているとは思いません。ループ内でAPI応答を待つ

onSearchSuccess = async (response) => { 
    const persons = response._embedded.persons_search_collection; 
    const personsWithClasses = await persons.reduce(
    (acc, person) => { 
    const params = { 
     person_id: person.person_id, 
     date: '2017-01-05', 
     enrollment_status: 3, 
     class_status: 2, 
    }; 
    return getClasses(//this function does an GET request and returns the response 
     params, 
     (classesResponse) => { 
     const { classes } = classesResponse._embedded; 
     console.log(classes); //logs after the console.log below 
     return [...acc, { ...person, classes }]; 
     }, 
    () => acc, 
    ); 
    }, []); 
console.log(personsWithClasses); //return undefined 
} 


export const getClasses = (params, success, error) => { 
    axios.get(`${uri}/classes`, { params }) 
    .then(({ data }) => { 
    success(data); 
    }) 
    .catch(err => error(err)); 
}; 
+0

'getClasses'クラスが約束を返した場合、' acc ... 'が約束するため' [... acc] 'を実行できません。なぜここで 'reduce'を使用していますか?あなたは何を達成しようとしていますか?すべてのRESTを順番に実行しますか?または、すべてのリクエストが完了するまで待ちます。 –

+0

基本的に私は人の配列を持っています。その人のためにその日のクラスがあり、その人とその人のクラスの両方を持つオブジェクトを返すならば、私は各人のクラスを取得する要求をしています。移動してください。私は基本的にクラスを持たない人を除外し、その人物のプロパティとクラスを持つ新しいオブジェクトを返したいと思っています。 –

+0

'getClasses'のコードを提供するのに役立つでしょうか? –

答えて

1

私がコメントで述べたように、reduceは、非同期機能を呼び出す場合、あなたが望むように機能しません。あなたは(私はasync/awaitにできるだけ多くを使用しようとした)ようにPromise.all.mapを使用することができます。

onSearchSuccess = async (response) => { 
    const persons = response._embedded.persons_search_collection; 
    let personsWithClasses = await Promise.all(persons.map(async (person) => { 
    try { 
     const classes = await getClasses({ 
     person_id: person.person_id, 
     date: '2017-01-05', 
     enrollment_status: 3, 
     class_status: 2, 
     }); 

     return {...person, classes}; 
    } catch(error) { 
     // ignore errors if a person wasn't found 
     return null; 
    } 
    })); 
    personsWithClasses = personsWithClasses.filter(x => x != null); 
    console.log(personsWithClasses); 
} 


export const getClasses = params => { 
    return axios.get(`${uri}/classes`, { params }); 
}; 

また、私はgetClassesに加えられた変更に注意してください。とにかくaxios.getが約束を返すなら、コールバックを受け入れる理由はありません。

+0

ありがとうございました!私は使用していたpromise.allコードで更新するのを忘れましたが、私は近づいていました。ちょうどtry/catch部分がありませんでした。 –

関連する問題