设置文本D3时使用异步调用

时间:2018-10-23 15:04:10

标签: javascript d3.js

我有一些类似于以下代码:

nodeEnter.append('text')
  .text(async function(d) {
    var count = await dispatch('GetCount', {
      chosenNode: d
    });
    return count || 'N/A';
  });

运行此命令时,显示的文本如下所示:

[object Promise]

该函数有效,但显然在promise返回任何内容之前返回。我该如何等待类似于以上代码的操作?

我将Vuex与VueJs一起使用,这就是分派正在处理的东西。

1 个答案:

答案 0 :(得分:2)

d3 .text()方法在异步/等待中不能很好地发挥作用。

您看到的Promise对象是因为async function()...返回了Promise。即使您只是从异步修饰函数中返回一个常量,您仍然会收到发送到d3 text()方法的承诺。

这是d3的text()方法的来源

function textRemove() {
  this.textContent = "";
}

function textConstant(value) {
  return function() {
    this.textContent = value;
  };
}

function textFunction(value) {
  return function() {
    var v = value.apply(this, arguments);
    this.textContent = v == null ? "" : v;
  };
}

export default function(value) {
  return arguments.length
      ? this.each(value == null
          ? textRemove : (typeof value === "function"
          ? textFunction
          : textConstant)(value))
      : this.node().textContent;
}

幸运的是,当一个函数被传递时,它是通过apply()方法调用的,该方法绑定了d3'this'上下文,因此我们可以轻松地在textContent内执行.then()赋值像这样

/* 
  Because the 'this' context changes below, need to grab 'dispatch' here
  This is specific to Vuex implementation mentioned in the question
  When using a different async function, just make sure it's within closure
*/
const dispatch = this.$store.dispatch  

nodeEnter.append('text')
  .text(function(d) {
    dispatch('GetCount', {
      chosenNode: d
    }).then(val => {
      this.textContent = val  // This is normally done in d3's text() method
    })

    /* 
      Don't return anything.
      d3's text() method will receive 'undefined'
      and not update textContent
    */
    // return count || 'N/A';
  });