在循环中等待 API 响应
Await for API response in a loop
我正在遍历一个数组并对每个项目进行 REST API 调用,但我在 js 的异步特性方面遇到了麻烦。我正在尝试使用 async/await 但我认为我没有正确设置它,因为它不会等待响应并且 returns 未定义。
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));
};
正如我在评论中提到的,如果您调用异步函数,reduce
将无法正常工作。你可以这样使用Promise.all
和.map
(我尽量使用async/await
):
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
returns 无论如何,没有理由让它接受回调。
我正在遍历一个数组并对每个项目进行 REST API 调用,但我在 js 的异步特性方面遇到了麻烦。我正在尝试使用 async/await 但我认为我没有正确设置它,因为它不会等待响应并且 returns 未定义。
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));
};
正如我在评论中提到的,如果您调用异步函数,reduce
将无法正常工作。你可以这样使用Promise.all
和.map
(我尽量使用async/await
):
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
returns 无论如何,没有理由让它接受回调。