У меня есть массив учетных записей, и есть два запроса: получить домен и получить данные учетной записи. если мне нужно получить все данные учетных записей, как я могу это сделать?
accountsData = acounts.map(account => {
getDomain(account).then(domain => getData(domain))
})
Promises.all(accountsData).then(e => console.info(e))
Поскольку несколько запросов все терпят неудачу, это не работает.
Я пробовал вышеуказанный подход, и он не работает, когда несколько запросов не выполняются.
Да это тоже не работает.
Также, поскольку я использую es2015, поэтому я не думаю, что это будет работать.
См. stackoverflow.com/questions/36094865/…
Вы ничего не возвращаете из обратного вызова map.
Мой массив обещаний выглядит так. [Обещание, Обещание, Обещание] 0: Обещание _U: 1 _V: 1 _W: некоторые данные _X: null 1: Обещание _U: 1 _V: 1 _W: Ошибка: плохой ответ _X: null
@SayrasJain Для этого вы можете использовать Promise.allSettled. Мой ответ ниже может помочь вам узнать больше о том, как это работает.
Используйте Promise.allSettled, чтобы проверить, выполнено ли обещание или отклонено.
Вы можете поместить обещания в массив и использовать Promise.allSettled для массива обещаний.
for (const account of accounts) {
getDomainPromises.push(getDomain(account));
}
await Promise.allSettled(getDomainPromises).then((getDominResults) =>
getDominResults.forEach((getDomainResult) => {
if (getDomainResult.status === 'fulfilled'){
console.info("GD - " + getDomainResult.status, getDomainResult.value);
getDataPromises.push(getData(getDomainResult.value))
} else { // status = 'rejected'
console.info("GD - " + getDomainResult.status);
}
})
);
await Promise.allSettled(getDataPromises).then((getDataResults) =>
getDataResults.forEach((getDataResult) => {
if (getDataResult.status === 'fulfilled'){
console.info("getData - ", getDataResult.value)
} else { // status = 'rejected'
console.info("getData - REJECTED");
}
})
);
// Mocking getDomain Promise
function getDomain(a) {
return new Promise((resolve, reject) => {
if (a % 2 === 0) {
setTimeout(resolve, 100, 'RESOLVE - getDomain - ' + a);
} else {
setTimeout(reject, 100, 'REJECTED - getDomain - ' + a);
}
})
}
// Mocking getData Promise
function getData(a) {
return new Promise((resolve, reject) => {
if (Math.round(Math.random()*100) % 2 === 0) {
setTimeout(resolve, 100, 'RESOLVE - getData - ' + a);
} else {
setTimeout(reject, 100, 'REJECTED - getData - ' + a);
}
})
}
// SOLUTION::
const accounts = [1, 2, 3, 4];
const getDomainPromises = [];
const getDataPromises = [];
for (const account of accounts) {
getDomainPromises.push(getDomain(account));
}
async function run() {
await Promise.allSettled(getDomainPromises).then((getDominResults) =>
getDominResults.forEach((getDomainResult) => {
if (getDomainResult.status === 'fulfilled'){
console.info("GD - " + getDomainResult.status, getDomainResult.value);
getDataPromises.push(getData(getDomainResult.value))
} else { // status = 'rejected'
console.info("GD - " + getDomainResult.status);
}
})
);
await Promise.allSettled(getDataPromises).then((getDataResults) =>
getDataResults.forEach((getDataResult) => {
if (getDataResult.status === 'fulfilled'){
console.info("getData - ", getDataResult.value)
} else { // status = 'rejected'
console.info("getData - REJECTED");
}
})
);
}
run();
Вам нужно вернуть Promise на каждой итерации карты
accountsData = acounts.map(account => {
return new Promise((resolve, reject) => {
getDomain(account)
.then(domain => getData(domain)
.then(data => resolve(data)))
});
})
// e would be of the format [data1, data2, .....]
Promises.all(accountsData).then(e => console.info(e))
Вам не нужно создавать и возвращать новый промис в явном виде, поскольку getDomain() сам по себе является промисом. Так что просто return getDomain(account).then(getData); должно хватить
А вы пробовали Promise.allSettled ?