Скажем, у меня есть что-то вроде:
const exampleFunction = () => {
const fetchActions = someArray.map(() => {
dispatch(action()).then(response => {
if (response?.data) {
dispatch(subAction({response: response.data}))
}
})
})
return Promise.all(fetchActions)
.then(()=> dispatch(finalAction()))
}
Моя проблема в том, что когда я отправляю свой finalAction, все действия были отправлены/разрешены, но не поддействия. Как я могу выполнить свою отправку (finalAction ())) ТОЛЬКО после того, как все действия и поддействия были разрешены?
🤔 А знаете ли вы, что...
JavaScript можно использовать для создания ботов и автоматизации задач в браузерах с помощью Puppeteer.
Проблема с вашим кодом в том, что вы ничего не возвращаете из обратного вызова someArray.map
, а это означает, что fetchActions
— это массив неопределенных значений, а не обещаний. Поэтому Promise.all
не будет ждать завершения действий по отправке или поддействий перед разрешением.
Чтобы решить эту проблему, вы можете попробовать следующее:
const exampleFunction = async () => {
const fetchActions = someArray.map(async () => {
const response = await dispatch(action());
if (response?.data) {
await dispatch(subAction({ response: response.data }));
}
});
await Promise.all(fetchActions);
await dispatch(finalAction());
};
В этом коде someArray.map
ничего не возвращает, но создает массив обещаний. Каждое обещание ожидает последнего ожидания внутри функции карты, то есть либо dispatch(subAction())
, либо undefined
. Это похоже на возврат массива этих значений в виде промисов.
Если вы хотите сделать это более явным, вы можете добавить оператор return внутри обратного вызова карты, например:
const fetchActions = someArray.map(async () => {
const response = await dispatch(action());
if (response?.data) {
return dispatch(subAction({ response: response.data }));
}
return undefined;
});
Проблема в том, что Promise.all([...promises])
разрешается, когда все promises
разрешаются, но ваш fetchActions
на самом деле не является массивом промисов (как вы задумали), потому что у них есть осиротевшие промисы с отключенной цепочкой промисов. Для того, чтобы снова соединить цепочку, нужно добавить return
.
const exampleFunction = () => {
const fetchActions = someArray.map(() => {
return dispatch(action()).then(response => {
if (response?.data) {
return dispatch(subAction({
response: response.data
}))
}
})
})
return Promise.all(fetchActions)
.then(() => dispatch(finalAction()))
}
См. здесь, чтобы узнать больше о цепочке промисов.
По сути, идея такова: если вы хотите, чтобы функция разрешилась после того, как обещание, вызванное внутри нее, будет разрешено, вам нужно return
это обещание.
Например:
const promiseA = () => {
promiseY();
};
const promiseB = () => {
promiseZ();
};
await Promise.all([promiseA(), promiseB()]);
Promise.all
выше немедленно разрешается, не дожидаясь promiseY
или promiseZ
, потому что они осиротевшие промисы.
Для того, чтобы дождаться их, должно быть так:
const promiseA = () => {
return promiseY();
};
const promiseB = () => {
return promiseZ();
};
await Promise.all([promiseA(), promiseB()]);