【问题标题】:d3.js v5 - Promise.all replaced d3.queued3.js v5 - Promise.all 替换 d3.queue
【发布时间】:2018-09-07 03:16:45
【问题描述】:

我使用 d3.js v4 已经有一段时间了,我了解到 Mike Bostock 已将 v5 版本中的 d3.queue 替换为 Promise 本机 JavaScript 对象。我想检查一下我编写的这段代码是否正确地(异步)排队这些 URL:

var makeRequest = function() {
    "use strict";

    var bli = [
        "http://stats.oecd.org/sdmx-json/data/BLI2013/all/all",
        "http://stats.oecd.org/sdmx-json/data/BLI2014/all/all",
        "http://stats.oecd.org/sdmx-json/data/BLI2015/all/all",
        "http://stats.oecd.org/sdmx-json/data/BLI2016/all/all",
        "http://stats.oecd.org/sdmx-json/data/BLI/all/all"
    ];

    var promises = [];

    bli.forEach(function(url) {
        promises.push(
            new Promise(function(resolve, reject) {
                d3
                    .json(url)
                    .then(function(response) {
                        resolve(response);
                    })
                    .catch(function(error) {
                        console.log("Error on: " + url + ". Error: " + error);
                        reject(error);
                    });
            })
        );
    });

    Promise.all(promises).then(function(values) {
        console.log(values);
    });
};

makeRequest();

代码似乎运行正常,但是,这是正确的代码还是有更好的方法(最佳实践方法)用于使用 Promise.all 和 d3.js 进行排队?是否正确执行了 catch 错误?

【问题讨论】:

  • 我刚刚回滚了这个问题,删除了d3v5 标签。致编辑,请阅读:meta.stackoverflow.com/a/338840/5768908。我们在删除d3v4 标签方面做了大量工作,显然这个过程将从这个新的d3v5 标签重新开始!这是建议的操作:问题应该只有d3.js 标签,无论版本如何。然后,如果问题特定于给定版本,则 OP 必须在标题或问题正文上指定版本。

标签: d3.js promise queue


【解决方案1】:

您可以大大简化该代码:您不必将new Promised3.json 一起使用,因为d3.json 本身会创建promise。

所以,你可以这样做:

var files = ["data1.json", "data2.json", "data3.json"];
var promises = [];

files.forEach(function(url) {
    promises.push(d3.json(url))
});

Promise.all(promises).then(function(values) {
    console.log(values)
});

或者,如果您喜欢code golf,则更短:

var files = ["data1.json", "data2.json", "data3.json"];

Promise.all(files.map(url => d3.json(url))).then(function(values) {
    console.log(values)
});

由于我无法在 S.O. 中使用 JSON 文件。 sn-p,检查这个 bl.ocks 中的控制台:https://bl.ocks.org/GerardoFurtado/f08993c9c729b0b3452ef1803ad9dcbf/c4b45c5acce6033085a667cbb7d34203d15de0f0

【讨论】:

  • 太棒了!但是,如果单个 URL 给出错误 - 例如,如果它不存在 - Promise 不会返回来自其他 URL 的结果,即使它们是正确的(您的代码和我的代码都受此影响)。有没有办法从返回数据的 URL 中返回值,或者 Promise.all 函数假定不能有任何错误?
  • @MarcoA.Ferra 这是一个不同的问题,专门与Promise.all() 相关,与 D3 无关。因此,为避免您的问题“过于宽泛”,我建议您将此问题发布为 new 问题,并带有 promise 标签和 without d3.js标记。
  • 我会这样做的。感谢您在上面的正确答案。
  • @MarcoA.Ferra 不用担心。还有 es6-promise 标签,当然也可以和 javascript 一起使用。
  • @v3nt 这太复杂了,无法在评论中回答,我建议您发布一个新问题。
【解决方案2】:

这是ES6 async functionsES6 array destructuring 的方法:

async function chart() {
  const [first, second] = await Promise.all([
    d3.json('data1.json'),
    d3.json('data2.json'),
  ])
  console.log('data2.json :', second)
}

chart()

【讨论】:

    【解决方案3】:

    如果您想根据自己的喜好清理数据,您还可以为数据添加格式化功能。 .then() 会将您的数据保存在一个不错的数组中,供您以后使用。

    const myData = d3.csv("data.csv", formatterFunction)
    .then(data => /* do whatever*/ )
    
    function formatterFunction(row){
      // do formatting
      return // formatted data
       }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-31
      • 2013-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多