CrazySynthax
CrazySynthax

Reputation: 15064

vue.js: replacement for async hooks

Let's assume that I write a vue.js component and I want to use lifecycle hook (in this case 'destroyed') that includes some async operation. I don't want to leave the hook before the async operation is fully committed. One option is to use the async-await feature of Javascript at all.

    export default {
      name: 'someComponent',
      data() {
        return {
          ...,
        };
      },
      async destroyed() {
         await someAsyncOperation()
     }
    }

I want to ask if there is any way to do it without async-await (maybe promises).

Upvotes: 2

Views: 1414

Answers (1)

zero298
zero298

Reputation: 26930

Vue doesn't care or acknowledge that your lifecycle hooks are asynchronous, it will not wait await them. Consider the example below. If the API worked the way that you interpreted it, you would not see the new thing until after the console.log printed. However, it appears immediately.

Additionally, the Vue docs don't state that the lifecycle hooks are asynchronous. It doesn't say that they are async and it doesn't provide an option for a callback to to infer when the hook has completed.

This is in contrast to some of the other hook APIs (like animations) that Vue has.

const $timeout = d => new Promise(r => setTimeout(r, d));

const thing = {
  template: "<div>Count: {{text}}</div>",
  data() {
    return {
      text: "foo"
    };
  },
  async created() {
    await $timeout(1000);
    console.log("hello");
  },
  async destroyed() {
    await $timeout(1000);
    console.log("goodbye");
  }
}

const app = new Vue({
  el: "#app",
  components: {
    thing
  },
  data() {
    return {
      things: []
    }
  },
  methods: {
    addThing() {
      this.things.push({});
    },
    removeThing() {
      this.things.pop();
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>

<div id="app">
  <button @click="addThing">+</button>
  <button @click="removeThing">-</button>
  <div v-for="thing in things">
    <thing></thing>
  </div>
</div>

Upvotes: 5

Related Questions