Answer the question
In order to leave comments, you need to log in
Problem with nested promises?
I need to take information from api and output to render. The first promise receives dialogs, and the nested promise pulls additional data from the api for each dialog in a loop. All this is inside componentDidMount, but as a result, the cards are not updated, and the data, judging by the screen, does not have time to load.
componentDidMount() {
// first request
fetch(`${this.WebApiHost}/api/dialogs/get/${this.CurrentContactId}`)
.then(function(res) {
return res.json();
})
.then((json) => {
if (!json || json.error == true) {
console.log("error");
} else {
// first request is ok!
this.state.Dialogs = [];
// for each dialog
json.dialogs.map((v) => {
let dialogId = v.dialogId;
// second request
fetch(`${this.WebApiHost}/api/qwe/dialogs/${dialogId}/${this.My_Token}`)
.then((res) => {
let jsonRes = res.json();
console.log(jsonRes);
return jsonRes;
})
// second request is ok
.then((json2) => {
let data = json2.data;
let msgDate = data == null ? "" : data.last_message.created;
let msgText = data == null ? "" : data.last_message.text;
this.state.Dialogs.push({dialogId:v.dialogId, from:v.transportName, date:msgDate, msg:msgText});
})
.catch((err) => {
this.setState({IsLoading:false, Error:err});
});
});
}
}).then(() => {
console.log("end");
console.log(this.state.dialogs);
this.setState({IsLoading:false});
})
.catch((err) => {
this.setState({IsLoading:false, Error:err});
});
}
Answer the question
In order to leave comments, you need to log in
You need to wait until all fetch().then().then()
, collecting them in an array.
const promises /* !!! */ = json.dialogs.map((v) => {
let dialogId = v.dialogId;
return /* !!! */ fetch(`${this.WebApiHost}/api/qwe/dialogs/${dialogId}/${this.My_Token}`)
// ....
});
await Promise.allSettled(promises);
async
/ await
and not use asynchronous functions in map
/ forEach
:try {
const resp = await fetch("");
const json = await resp.json();
if (!json || json.error === true) {
console.log("error");
}
async function handleDialog(dialog) {
try {
const resp = await fetch("");
const json = await resp.json();
// ...
} catch (e) {
// ...
}
}
const concurrently = false;
if (concurrently) {
// [Way 1] Run one by one ---------
for (const dialog of []) {
await handleDialog(dialog);
}
} else {
// [Way 2] Run all concurrently ---
const promises = [];
for (const dialog of []) {
promises.push(handleDialog(dialog));
}
await Promise.allSettled(promises);
}
// The best way: concurrently with limitation
// @see https://qna.habr.com/q/1105356#answer_2098042
// ...
} catch (e) {
// ...
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question