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

Posted

技术标签:

【中文标题】d3.json() 回调中的代码未执行【英文标题】:Code within d3.json() callback is not executed 【发布时间】:2020-07-03 03:04:24 【问题描述】:

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

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

代码如下:sn-p。

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 调用本身。

【问题讨论】:

【参考方案1】:

d3.json 的签名从 D3 v4 到 v5 具有 changed。它已从现已弃用的模块 d3-request 移至新的 d3-fetch 模块。从 v5 开始,D3 使用 Fetch API 代替旧的 XMLHttpRequest,并反过来采用 Promises 来处理这些异步请求。

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

您的代码因此变为:

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() 返回的承诺将被拒绝。因此,可以应用处理这些拒绝的 vanilla JS 方法:

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

    使用 .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.
  );

【讨论】:

@Timmmm,.then 方法可以提供一个可选的第二个函数,如果 promise 最终未实现,则调用该函数:.then(function(data) , function(error) ) @Timmmm 或者,您可以使用.catch(function(error) ),这与 Andrew 的建议大致相同,但更明确。 假设我们不能使用 V5 语法,而必须使用 V4。那我们该怎么办? @3xCh1_23 您只需使用问题中发布的原始代码即可。 @altocumulus 不起作用,这就是重点……但找到了一种解决方法,共享起来有点复杂……【参考方案2】:

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

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

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

而不是

d3.json("URL", function(data)

因此,一般模式变为:

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



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


initialFunction();

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

【讨论】:

以上是关于d3.json() 回调中的代码未执行的主要内容,如果未能解决你的问题,请参考以下文章

通过 Chrome 中的 Fetch API 在 D3 v5 中加载 JSON?

d3.js Faux-3D Arcs - Uncaught typeerror:无法读取未定义的属性“对象”

MessageCenter xamarin 表单的 lambda 回调中未执行的方法

d3 javascript中的变量范围

d3.json:“未捕获的类型错误:无法读取未定义的属性‘孩子’”

JavaScript回调函数未执行