test
test

Reputation: 18198

JavaScript - Yield until next function is finished

Let's say I have a simple Node.js app that has these methods in another file:

module.exports = {
  completeQuest(data) {
    // Code here
  },
  killMonster(data) {
    // Also code here
  },
};

And they are not AJAX commands. These just manipulate some data within the app. I'd export as such in allActions.js:

const player = require('./playerActions');

module.exports = {
  player,
};

and of course later, in main JS file const actions = require('./allActions');

So, generally, I'd do:

actions.player.killMonster();
actions.player.completeQuest();

But I want them to act one after the other. I know I can do async/await, but I'm not doing any AJAX calls, so would a Promise still be the best way?

What about using a yield function? Would that be good?

Upvotes: 0

Views: 171

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074495

I'm going to assume that killMonster and completeQuest perform asynchronous actions. (You've said they're "not ajax", but your question suggests they're not synchronous, either.)

Yes, this is a use case for promises, either explicit promises or those provided by async functions. Have killMonster and completeQuest return a promise (either by doing so explicitly or making them async functions), and then either:

actions.player.killMonster()
.then(
    () => actions.player.completeQuest()
)
.catch(error => {
    // Handle error
});

or, within an async function:

try {
    await actions.player.killMonster();
    await actions.player.completeQuest();
} catch (error) {
    // Handle error
}

Here's a simple async/await example using setTimeout to provide the asynchronous part:

const delay = (ms, ...args) =>
  new Promise(resolve => {
    setTimeout(resolve, ms, ...args);
  });

// Stand-ins for the actions
const player = {
  actions: {
    async killMonster() {
      await delay(500, "monster killed");
    },
    async completeQuest() {
      await delay(800, "quest complete");
    }
  }
};

// Top-leve async function (see my answer here:
// https://stackoverflow.com/questions/46515764/how-can-i-use-async-await-at-the-top-level
(async () => {
  try {
    console.log("Killing monster...");
    await player.actions.killMonster();
    console.log("Monster killed; completing question...");
    await player.actions.killMonster();
    console.log("Quest complete");
  } catch (e) {
    // Deal with error (probably don't just dump it to the console like this does)
    console.error(e);
  }
})();

Upvotes: 2

Related Questions