nodejs - возвращение обещания после окончания цикла for - PullRequest
0 голосов
/ 20 октября 2018

Мне нужно вызвать функцию async в цикле for, где каждая итерация "строит" объект.В конце цикла этот объект должен быть разрешен в Promise, чтобы следующая функция в цепочке могла забрать его для дальнейшей обработки.Хотя итерации правильно получают данные, я не могу собрать «построенный» объект и вернуть его.Я продолжаю получать {}.Можете ли вы помочь мне решить эту проблему?

async function imageDetailsCache(images) {
    var imageData = {}; // This object is built up every iteration
    var imageNo = '';
    var promises = [];
    //
    for (let i = 0; i < images.length; i++) {
        imageNo = images[i]
        promises.push(
            new Promise(function (resolve, reject) {
                imageDetails(imageNo, 'BIG').then(function (result) {
                    imageData[imageNo] = { 'BIG': result }
                    imageDetails(imageNo, 'TINY').then(function (result) {
                        imageData[imageNo] = { 'TINY': result }
                    })
                })
                resolve(imageData)
            })
        )
    }
    Promise.all(promises).then(function (result) {
        return result; // Always {}
    })
}

Ответы [ 2 ]

0 голосов
/ 21 октября 2018

Если вы хотите использовать обещания, тогда: я думаю, это будет работать:

async function imageDetailsCache(images) {
var imageData = {};
var promises = [];
for(let i = 0; i < images.length; i++) { // notice the let instead of var
   promises.push(
         new Promise( (resolve, reject) => {
            imageDetails(images[i], 'BIG')
                .catch(e => {reject(e)})
                .then( rBig => {
                    imageDetails(images[i], 'SMALL')
                        .catch(e => { reject(e)})
                        .then( rSmall => {
                            imageData[images[i]] = {
                                 'BIG': rBig ,
                                 'SMALL': rSmall
                            }
                            resolve ({
                                BIG: rBig,
                                SMALL: rSmall
                            });
                        });
                    });
                }
            )
        );
}
await Promise.all(promises);
return imageData;

}

imageDetailsCache (images) .then ((r) => {console.log(r)});

Я должен подчеркнуть, что использование async & await правильно (как предложено https://stackoverflow.com/users/1048572/bergi) сделает этот код чище.

Лично я бы сделалэто так:

async function imageDetailsCache(images) {
var imageData = {};
var promises = [];
for(let i = 0; i < images.length; i++) {
    try {
        imageData[images[i]] = {
            'BIG': await imageDetails(images[i], 'BIG') ,
            'SMALL': await imageDetails(images[i], 'SMALL')
        }
    } catch (e)  {
        console.log(e);
    }
}
return imageData;

}

imageDetailsCache (images) .then ((r) => {console.log (r)});

Надеюсьпомогает!

0 голосов
/ 20 октября 2018

Избегайте использования 1002 * конструктора antipattern !Вы звонили resolve до того, как произошли асинхронные события в imageDetails.И не используйте then при работе с async / await:

async function imageDetailsCache(images) {
    var imageData = {}; // This object is built up every iteration
    var promises = images.map(async (image) => {
        var result = await imageDetails(image, 'BIG');
        imageData[image] = { 'BIG': result }
        var result = await imageDetails(image, 'TINY');
        imageData[image] = { 'TINY': result };
    });
    await Promise.all(promises);
    return imageData;
}
...