d3.json() 回调中的代码未执行

IT技术 javascript d3.js
2021-01-12 16:22:16

我正在尝试加载一个 GeoJSON 文件并使用它作为 D3 v5的基础绘制一些图形

问题是浏览器会跳过d3.json()调用中包含的所有内容我尝试插入断点进行测试,但浏览器跳过了它们,我不知道为什么。

下面的代码片段。

d3.json("/trip_animate/tripData.geojson", function(data) {

  console.log("It just works");  // This never logs to console.

  //...all the rest
}

代码从最初的 继续console.log(),但我省略了所有它,因为我怀疑问题出在d3.json调用本身上。

2个回答

的签名d3.json已经改为从D3 V4到V5。它已从现已弃用的module d3-request 移至新的d3-fetchmodule。从 v5 开始,D3 使用Fetch API来支持旧的XMLHttpRequest,并反过来采用Promises来处理这些异步请求。

d3.json()no的第二个参数是处理请求的回调,而是一个可选RequestInit对象。d3.json()现在将返回一个您可以在其.then()方法中处理的 Promise

您的代码因此变为:

d3.json("/trip_animate/tripData.geojson")
  .then(function(data){
    // Code from your callback goes here...
  });

随着 Fetch API 的引入,调用的错误处理也发生了变化。v5 之前的版本使用传递给回调的第一个参数d3.json()来处理错误:

d3.json(url, function(error, data) { 
  if (error) throw error;
  // Normal handling beyond this point.
});

从 D3 v5 开始,d3.json()如果遇到错误,则返回的Promise将被拒绝。因此,可以应用处理这些拒绝的普通 JS 方法:

  1. 将拒绝处理程序作为第二个参数传递给.then(onFulfilled, onRejected)

  2. 用于.catch(onRejected)向Promise添加拒绝处理程序。

应用第二个解决方案,您的代码就变成了

d3.json("/trip_animate/tripData.geojson")
  .then(function(data) {
    // Code from your callback goes here...
  })
  .catch(function(error) {
    // Do some error handling.
  });
@3xCh1_23 您只需使用问题中发布的原始代码。
2021-03-16 16:22:16
假设我们不能使用 V5 语法,而必须使用 V4。那我们该怎么办呢?
2021-03-17 16:22:16
@altocumulus 不起作用,这就是重点......但找到了一种解决方法,分享起来有点复杂......
2021-03-18 16:22:16
@Timmmm,.then 方法可以提供一个可选的第二个函数,如果Promise最终未实现,则调用该函数: .then(function(data) {}, function(error) {})
2021-03-27 16:22:16
@Timmmm 或者,您可以使用.catch(function(error) {}),这主要相当于安德鲁的提议,但在口头上更加明确。
2021-04-03 16:22:16

由于没有任何答案有帮助,我不得不自己找到有效的解决方案。我正在使用 v4 并且必须坚持下去。问题是(在我的情况下)d3.json 第一次工作,但第二次或第三次没有工作(使用 HTML 下拉菜单)。

这个想法是使用初始函数,然后简单地使用第二个函数

让数据 = 等待 d3.json("URL");

代替

d3.json(“网址”,功能(数据){

因此,一般模式变为:

async function drawWordcloudGraph() {
    let data = await d3.json("URL");
    ...
}


function initialFunction() {
    d3.json("URL", function (data) {
        ...
    });
}

initialFunction();

我尝试了几种方法,只有这种方法有效。不确定是否可以简化,请自行测试。