Я понимаю основную концепцию ожидания, асинхронности и промисов. Я пробовал много из них, но не мог получить ожидаемый результат. По этой причине я прошу вас, ребята, о помощи. Спасибо заранее.
Я выкинул все ненужные строки кода, чтобы вы могли быстро увидеть, что я хочу сделать.
app.post('/create', (req,res) => {
var dataArray = []
req.body.array.forEach((ele) => {
let blobAdress = ele.link.split('/')[0];
let extracted = ele.extracted
let blob = `${blobAdress}/extracted-${extracted}.json`;
const container = 'test';
//SHOULD BE EXECUTED FOR EACH ELEMENT OF FOR LOOP
api.getTextFromBlob(container, blob, (response, error) => {
if (error){console.info("Error",error)}
let jsonResponse = JSON.parse(response);
console.info(jsonResponse)
dataArray.push(jsonResponse) // I WANT ALL DATA FROM THE CB IN ONE ARRAY BUNDLED
})
})
// RUN THIS PART AFTER FOR LOOP HAS BEEN EXECUTED PROPER
console.info(dataArray) // !ASYNC JS --> DATA ARRAY IS EMPTY BECAUSE datArray IS CONSOLE.LOG BEFORE api.getText EXECTUED
})
Сначала вам нужно обернуть функцию обратного вызова в объект Promise:
var getTextFromBlobAsPromise = (container, blob) => new Promise((resolve, reject) => {
api.getTextFromBlob(container, blob, (response, error) => {
if (error) {
console.info("Error", error)
return reject(error); // depends on business
}
let jsonResponse = JSON.parse(response);
console.info(jsonResponse)
resolve(jsonResponse);
})
})
Затем вы можете дождаться, пока все промисы будут разрешены, используя функцию Promise.all:
app.post('/create', (req, res) => {
var promises = [];
req.body.array.forEach((ele) => {
let blobAdress = ele.link.split('/')[0];
let extracted = ele.extracted
let blob = `${blobAdress}/extracted-${extracted}.json`;
const container = 'test';
//SHOULD BE EXECUTED FOR EACH ELEMENT OF FOR LOOP
promises.push(getTextFromBlobAsPromise(container, blob)) ;
})
// RUN THIS PART AFTER FOR LOOP HAS BEEN EXECUTED PROPER
Promise.all(promises).then(dataArray => {
console.info(dataArray) // !ASYNC JS --> DATA ARRAY IS EMPTY BECAUSE datArray IS CONSOLE.LOG BEFORE api.getText EXECTUED
})
})
Promise.all гарантирует, что массив ответов имеет тот же порядок, что и массив обещаний. Таким образом, в этом примере у вас столько одновременных запросов, сколько req.body.array
длины. После .then()
в dataArray будут все ответы.
Однако, если какой-то запрос не будет выполнен, весь Promise.all() будет отклонен. Тогда вам может понадобиться блок .catch(err => {})
сразу после then()
.
Нет, это ненормально. Убедитесь, что Promise.all()
запускается только один раз за запрос.
У меня также была ошибка во внешнем интерфейсе, где я запускал эту функцию, которая отвечала за все разные длины. Thx 4 вы помогаете.
Спасибо за ваш ответ. Но когда я запускаю его и регистрирую dataArray.length, я получаю 3 разных результата (размер req.body.array) в разных порядках. между 1,2,3. Но мне нужен массив со всеми тремя ответами. Что я могу сделать здесь?