使用Promise.all(...)。then

时间:2020-04-02 14:30:58

标签: javascript asynchronous es6-promise

以下代码有误,但我无法弄清楚。我相信,当我执行Promise.all(...)。then时,所有的诺言都应在这一点上完成,但是看起来并不像它。 。 该代码仅从api中获取了一些json,然后向DOM中添加了一些html元素。但是,这些新元素以某种方式不会在Promise.all的.then部分中注册。

let urls = [];

urls.push(someurl);
urls.push(someurl2);

Promise.all(urls.map(url => {
    fetch(url)
        .then(response => {
            return response.json();
        })
        .then(data => {

            ... // do something with the current json and add some <option> elements to the DOM

            let options = document.querySelectorAll('option');
            console.log(options); //is filled with the correct options!


        })
})).then(data => {

    let options = document.querySelectorAll('option');
    console.log(options); // IS EMPTY!!! I expected to see the two sets of the <option> elements

});

生成的HTML看起来应该在前端,但是.then中的DOM不在我期望的状态。因此,我无法使用materializecss库,因为我无法用元素填充选择下拉列表。好像它们尚未在.then中初始化选择下拉列表的位置创建。 感谢您的帮助!

解决方案:只需在获取之前放一个退货!!感谢所有为我指出正确方向的人。我不知道为什么Promise.all(...)。即使没有正确的返回值也要执行,但这已经解决了。

3 个答案:

答案 0 :(得分:2)

您可以尝试更新map()方法以返回获取响应,例如:

Promise.all(urls.map(url => fetch(url).then(resp => resp.json())))
   .then(data => {
      console.log(data);

      let options = document.querySelectorAll('option');
      console.log(options);
   })

请注意,在ES5中,我们将执行以下操作:

var multiply = function(x, y) {
  return x * y;
};

在ES6中,我们可以使用箭头功能,例如:

const multiply = (x, y) => { return x * y };

此处,return语句是必需的,否则它将返回未定义,但是{ ... }内部的语句仍将执行,仅不返回计算出的值。因此,在您的代码中fetch有效,但最后一个.then无效。

此外,如果仅存在一个表达式,则不需要大括号。因此,前面的示例也可以写成:

const multiply = (x, y) => x * y;

答案 1 :(得分:1)

我不知道为什么Promise.all(...)。即使没有正确的返回值也要执行,但这已经解决了。

在没有丢失return的情况下,您正在传递Promise.all()的一组undefined值。由于该数组中没有承诺,因此Promise.all()无需等待,因此它立即调用了.then()处理程序。这就是为什么它不等待完成就执行的原因。如果您希望它等待,则必须传递Promise.all()一系列的诺言。

答案 2 :(得分:0)

解决方案:在获取之前缺少回报。我不知道为什么.then甚至在没有返回的情况下仍在运行,但这已经解决了。另一个解决方案是在此示例中删除大括号。现在一切都按我的预期进行。

相关问题