0

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? I'm looking for opinions is all. Thank you.

test
  • 17,706
  • 64
  • 171
  • 244
  • 1
    *"But I want them to act one after the other."* That's...how functions work. One runs to completion, then the next does. What are you seeing instead? We may need to know more about the implementation of the functions. You've said their "not ajax" which I assumed meant they didn't do asynchronous work, but then your question at the end suggests otherwise... – T.J. Crowder Sep 24 '18 at 06:21
  • so, `completeQuest` and `killMonster` are async functions, right? – Alejandro Sep 24 '18 at 06:21
  • @T.J.Crowder You are right. I messed my wording. – test Sep 24 '18 at 06:49

1 Answers1

2

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);
  }
})();
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks. IT seems like async/await is still best way to go even when no AJX is involved. – test Sep 24 '18 at 06:50