简体   繁体   中英

Using asynchronous call when setting text D3

I have some code similar to the following :

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

When running this, the text that shows looks like this :

[object Promise]

The function works but obviously returns before the promise returns anything. How would I go about awaiting an action in code similar to the above ?

I am using Vuex with VueJs, that's what the dispatch is working with.

The d3 .text() method does not play well with async / await.

The promise object you see is because async function()... is returning a promise. Even if you just return a constant from an async decorated function, you still get a promise sent to the d3 text() method.

Here is the source of d3's text() method

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

Luckily, when a function is passed it is invoked with the apply() method which binds the d3 'this' context, so we can easily carry out the textContent assignment within the .then() callback of the promise, like so

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM