у меня проблема:
Я хочу, чтобы мой axios выполнил требование и после этого сделал this.setState с результатом, сохраненным в переменной.
Мой код:
componentDidMount() {
let mails = [];
axios.get('/api/employee/fulano')
.then(res => this.setState({
employees: res.data
}, () => {
this.state.employees.map(i => {
async axios.get(`/api/status/${i.mail}`)
.then(res => {
mails.push(res.data)
await this.setState({
mails: mails
})
})
.catch(err => console.info(err))
})
}))
.catch(err => console.info(err))
}Но дает синтаксис ошибки.
Лучшее объяснение: я хочу сохранить все результаты карты в переменной mails, а затем использовать setState для изменения результата только на время.
Кто-нибудь может сказать мне, где я блуждаю? Пожалуйста.
Чтобы решить вашу актуальную проблему, вам нужен Promise.all.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Это должно работать:
componentDidMount() {
axios.get('/api/employee/fulano')
.then(res => this.setState({
employees: res.data
}, () => {
this.state.employees.map(i => {
axios.get(`/api/status/${i.mail}`)
.then( async (res) => { // Fix occurred here
let mails = [].concat(res.data)
await this.setState({
mails: mails
})
})
.catch(err => console.info(err))
})
}))
.catch(err => console.info(err))
}
добро пожаловать в stackoverflow! Пожалуйста, уточните еще немного. Другой ответ выглядит лучше, даже если он был дан после вашего: и это потому, что есть объяснение.
Вы поставили async не в то место
async следует помещать в определение функции, а не в вызов функции
componentDidMount() {
let mails = [];
axios.get('/api/employee/fulano')
.then(res => this.setState({
employees: res.data
}, () => {
this.state.employees.map(i => {
axios.get(`/api/status/${i.mail}`)
.then(async (res) => {
mails.push(res.data)
await this.setState({
mails: mails
})
})
.catch(err => console.info(err))
})
}))
.catch(err => console.info(err))
}
Вы используете async await не в том месте. Ключевое слово async должно использоваться для функции, содержащей асинхронную функцию.
Ключевое слово await необходимо использовать для выражения, которое возвращает Promise, и хотя setState - это async, оно не возвращает обещание, и, следовательно, await не будет работать с ним.
Ваше решение будет выглядеть так
componentDidMount() {
let mails = [];
axios.get('/api/employee/fulano')
.then(res => this.setState({
employees: res.data
}, async () => {
const mails = await Promise.all(this.state.employees.map(async (i) => { // map function contains async code
try {
const res = await axios.get(`/api/status/${i.mail}`)
return res.data;
} catch(err) {
console.info(err)
}
})
this.setState({ mails })
}))
.catch(err => console.info(err))
}
Здравствуйте, спасибо за ответ, рада этому .. Но дано: await is a reserved word (20:22), почему?
@Jota, извините, отсутствовало ключевое слово async в функции обратного вызова setState, обновил мой ответ
Смешивать async/await с .then/.catch - не лучшая практика. Вместо этого используйте одно или другое. Вот пример того, как вы могли бы это сделать, используя ТОЛЬКОasync/await и ТОЛЬКО one this.setState() (ссылка на функцию Promise.each):
componentDidMount = async () => {
try {
const { data: employees } = await axios.get('/api/employee/fulano'); // get employees data from API and set res.data to "employees" (es6 destructing + alias)
const mails = []; // initialize variable mails as an empty array
await Promise.each(employees, async ({ mail }) => { // Promise.each is an asynchronous Promise loop function offered by a third party package called "bluebird"
try {
const { data } = await axios.get(`/api/status/${mail}`) // fetch mail status data
mails.push(data); // push found data into mails array, then loop back until all mail has been iterated over
} catch (err) { console.error(err); }
})
// optional: add a check to see if mails are present and not empty, otherwise throw an error.
this.setState({ employees, mails }); // set employees and mails to state
} catch (err) { console.error(err); }
}
Почему вы даже пытаетесь использовать
async/await, если вас устраивает использованиеthenиcatch?