在做其他事情之前,我如何等待循环中的诺言完成?

时间:2019-03-23 04:31:43

标签: node.js promise

我仍然对如何使用承诺感到困惑。我有一个for循环调用异步方法,该方法返回一个值。我用这个值推入一个数组。但是当我打印数组时它是空的。这是我所做的:

async function getLink(link) {
    var browser = await puppeteer.launch({headless: true});
    const page = await browser.newPage();
    await page.goto(LINK)
    const result = await page.evaluate( async() => {
        let data = [];
        const $ = window.$;
        $('#gallery_01 .item').each(function(index, product) {
            data.push($(product).find('a').attr('data-image'));
        });
        return data;
    });
    await browser.close();
    return result;
}
var final = [];
for (var i = 0; i < 10; i++) {
        var data = getLink(value[i].url).then(function(data) {
            console.log(data); // urls show here
            final.push(data);
        });
}
Promise.all(final).then(() => {
        console.log(final) // empty
})

final显示为空。我对Promise做错了什么?请帮助!

2 个答案:

答案 0 :(得分:2)

我看不到value是什么,但看起来应该是具有url属性的对象数组?

假设getLink()函数正常,请为您的循环尝试以下操作:

const final = [];
for (var i = 0; i < 10; i++) {
  final.push(getLink(value[i].url));
}

Promise.all(final)
  .then(data => {
    console.log(data);
  });

或更简单的完成同一件事的方式:

const promises = value.map(v => getLink(v.url));

Promise.all(promises)
  .then(data => {
    console.log(data);
  });

答案 1 :(得分:1)

更新:不好,有点困惑。以下代码仅在() =>

之后没有var fn的情况下工作

您非常亲密。试试这个:

var final = [];
var results = []; // you need a separate array for results
for (var i = 0; i < 10; i++) {
       // renamed the variable, changed 'data' to 'fn' 
        var fn = () => getLink(value[i].url).then(function(data) {
            console.log(data); // urls show here
            results.push(data); 
        });
        final.push(fn);
}
Promise.all(final).then(() => {
        console.log(results) 
})

Promise.all接受一系列的诺言。您有一个“最终”数组,但似乎试图存储功能执行的结果以及函数本身。

要正确执行此操作-首先获得一个诺言数组。然后将它们传递给Promise.all()。

P.S。假设您的功能确实有效,请不要去看它,因为问题在于承诺。