代码之家  ›  专栏  ›  技术社区  ›  thatOneGuy

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

  •  3
  • thatOneGuy  · 技术社区  · 8 年前

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

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

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

    [object Promise]
    

    函数可以工作,但很明显在承诺返回任何东西之前就返回了。我将如何在类似于上述代码的代码中等待操作?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Richard Matsen    7 年前

    d3 .text()

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

    这是d3的来源 文本() 方法

    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';
      });