Я борюсь в течение нескольких дней за довольно простую проблему, я думаю.
У меня есть несколько вызовов, как это
for(var i = 1; i <= timeToIterate;i++){
xapi.fetch({})
.then(function (response) {
response.results.forEach(y => {
yapi.fetch({})
.then(function (response2){
//some treatment here with
response.articles.forEach(article => {
finalArray.push({})
});
})
});
}
Нет проблем, пока все работает нормально, но теперь я хочу выполнитькод с моим finalArray после того, как все закончено. но когда я попытался поставить затем после второй, но она не выполняется должным образом, я попытался поставить после цикла for, но все еще пустой. Я даже пытался с некоторым ожиданием, но я не могу понять, как выполнить код, когда все тогда закончено.
Заранее спасибо.
РЕДАКТИРОВАТЬ: больше теста с ответом
var count = 0; //just to know how many articles
var completeArray = [];
var promise_arr = [];
xapi.fetch({})
.then(async function (responseJson) {
var timeToIterate = Math.ceil(responseJson.totalResultNumber / 50);
for(var i = 1; i <= timeToIterate;i++){
p = yapi.fetch({})
.then(function (responseJson) {
if (responseJson.results.length > 0){
responseJson.results.forEach(x => {
zapi.fetch({})
.then(function (response) {
response.articles.forEach(article =>{
count++;
console.log(count);
completeArray.push({article};
});
}).catch(e => {
console.log(e);
})
});
}
}).catch(e => {
console.log(e);
})
promise_arr.push(p);
}
await (Promise.all(promise_arr));
console.log('now '+ completeArray.length);
const insert = elasticClient.bulk(
{body: completeArray},function (err, resp) {
completeArray = [];
if(resp.errors) {
console.log(JSON.stringify(resp, null, '\t'));
}
});
}).catch(e => {
console.log(e);
}).then(function(){
return res.json(count);
})
Но он все еще срабатывает до окончания функции for. Я что-то пропустил ? Я попытаюсь со вторым ответом!
РЕДАКТИРОВАТЬ 2: Я пробовал второй ответ тоже, но не могу найти, как заставить это работать без ошибки, я новичок с синей птицей, не знал это прежде сегодня
var count = 0;
var completeArray = [];
let response0 = await api1.fetch({});
await Promise.map(response0.results, async z => {
console.log(z); //Good log here
var timeToIterate = Math.ceil(z.totalResultNumber / 50);
for (var i = 1; i <= timeToIterate; i++) {
let response = await api2.fetch({});
await Promise.map(response.results, async x => {
console.log(x) // No Log here
let response2 = await api3.fetch({});
await Promise.map(response2, y => {
if (y.sections && y.sections.length > 0) {
y.sections.forEach(section => {
if (section.articles.length > 0) {
lawSection.articles.forEach(article => {
count++;
console.log(count);
completeArray.push(article)
});
}
})
} else if (y.articles && y.articles.length > 0) {
y.articles.forEach(article => {
count++;
console.log(count);
completeArray.push(article);
});
}
});
});
}
console.log('now ' + completeArray.length); // got this log Z time but nothing above so completeArray.length always = 0
const insert = elasticClient.bulk({
body: completeArray
}, function (err, resp) {
completeArray = [];
if (resp.errors) {
console.log(JSON.stringify(resp, null, '\t'));
}
});
});
РЕДАКТИРОВАТЬ 3: Благодаря @tadman я понял это, но все еще есть проблема асинхронности для моего эластичного клиента, вот мой код
var count = 0;
var completeArray = [];
let response0 = await api1.fetch({});
await Promise.map(response0.results, async z => {
var timeToIterate = Math.ceil(response0.totalResultNumber / 50);
for (var i = 1; i <= timeToIterate; i++) {
let response = await api2.fetch({});
await Promise.map(response.results, async x => {
if(response2.sections && response2.sections.length > 0){
response2.sections.forEach(section => {
if (section.articles.length > 0) {
section.articles.forEach(article => {
count++;
console.log(count);
completeArray.push(article);
});
}
})
} else if (response2.articles && response2.articles.length > 0) {
response2.articles.forEach(article => {
count++;
console.log(count);
completeArray.push(article)
});
}
});
// I have to put it here because if i put it after the for loop the request http is to big and i have a 413 response. But the problem here is it didn't wait for the callback for the next 'for' loop iteration ! So i have the right number with my 'count' variable but didn't have the right number in my database
console.log('now ' + completeArray.length);
await elasticClient.bulk( //how can i wait for the end of this and apply the completeArray = [] before the next iteration ?
{refresh: "wait_for",body: completeArray},
async function(err, response) {
completeArray = [];
if (err) { console.log(err); return; }
console.log(`Inside bulk3...`);
let errorCount = 0;
response.items.forEach(item => {
if (item.index && item.index.error) {
console.log(++errorCount, item.index.error);
}
});
console.log(`Successfully indexed items`);
}
)
}
});