Callback/Promise вложенный цикл, 2 вызова API

110
14

Мои извинения за титул я не мог найти ничего лучше. если эта проблема имеет ответ, уже не стесняйтесь сообщать мне в комментариях ниже и плохо удалять ее сразу, но помните об этом, это не общий вопрос.

Объяснение: Существует вызов API, который будет извлекать данные с сервера (массива), а затем на основе этого массива он запустит цикл, внутри цикла у нас есть другой API на основе родительского индекса (вызов child make API с использованием родительского индекса ) и получить некоторые данные и перечислить их в переменную (массив). Мне нужно вызвать обратный вызов после того, как последний ребенок последнего родителя выполнил свою работу.

Мимический код:

for(let i=0;i<2;++i){
for(let j=0;j<2;++j){
map data into another array with predefined shape
console.log(i +", "+ j)
}
}
console.log('good to go for callback');

Желаемый результат

0, 0
0, 1
1, 0
1, 1
good to go for callback

Реальный код:

var projects = api.getProjects(req);

projects.then(function(response){
response.projects.map(_e => {
var project = api.getProjectContent(_e.id);
project.then(function(_response){
_response.content.map(e=> {
a_globa_array.push(...);
console.log('hello');
});
});
});

console.log('yellow');
});

Я хочу, чтобы точно после каждого отдельного ребенка от каждого отдельного родителя, помещенного в массив, напечатайте "желтый" в консоли (или получите длину массива).

То, что я пробовал до сих пор:

var projects = api.getProjects(req);

projects.then(function(response){
Promise.all(response.projects.map(_e => {
var project = api.getProjectContent(_e.id);
project.then(function(_response){
_response.content.map(e=> {
a_globa_array.push(...);
console.log('hello');
});
});
})).then(()=>{ console.log('yellow'); });
});

А также

var projects = api.getProjects(req);

projects.then(function(response){
let pr = new Promise((resolve, reject) => {response.projects.map(_e => {
var project = api.getProjectContent(_e.id);
project.then(function(_response){
_response.content.map(e=> {
a_globa_array.push(...);
console.log('hello');
});
});
})) });

pr.then(()=>{ console.log('yellow'); });
});

И еще. Typo в вышеуказанных кодах не важны, потому что я написал их в редакторе SO, поэтому, возможно, я пропустил некоторые скобки/фигурные скобки. Дополнительная информация: Ошибок нет. Если вы считаете, что есть лучшие решения, а не обещание (async/await...), пожалуйста, дайте мне знать и поделитесь своими мыслями.

спросил(а) 2021-01-19T18:39:43+03:00 6 месяцев, 1 неделя назад
1
Решение
64

Ваша первая попытка была не так далека. Вам просто не нужно забывать return обещания из ваших обратных вызовов, чтобы, например, then или Promise.all могли их ждать:

projects.then(function(response){
return Promise.all(response.projects.map(_e => {
// ^^^^^^
var project = api.getProjectContent(_e.id);
return project.then(function(_response) {
// ^^^^^^
return _response.content.map(e=> {
// ^^^^^^
console.log('hello');
return ...;
// ^^^^^^
});
});
}));
}).then(array_of_arrays => {
// ^^^^^^^^^^^^^^^ you get the results here
// you can un-nest this then() call
console.log('yellow');
});

ответил(а) 2021-01-19T18:39:43+03:00 6 месяцев, 1 неделя назад
46

Вы почти получили его с первым фрагментом Promise.all, но функция внутри него не возвращает обещанного им обещания, поэтому вы вызываете Promise.all по массиву неопределенных.

Попробуйте это (то же самое, с добавленным return):

var projects = api.getProjects(req);

projects.then(function(response){
Promise.all(response.projects.map(_e => {
var project = api.getProjectContent(_e.id);
return project.then(function(_response){
_response.content.map(e=> {
a_globa_array.push(...);
console.log('hello');
});
});
})).then(()=>{ console.log('yellow'); });
});

Кроме того, я бы предложил избегать Array.map когда вы фактически не возвращаете никаких значений. Использование forEach вместо этого делает цель более четкой (карта используется для создания нового массива, а forEach - просто цикл).

ответил(а) 2021-01-19T18:39:43+03:00 6 месяцев, 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема