Doge Doge - 3 months ago 12
Node.js Question

Triggering Promise.fulfill on an outer-scope event

I'm using a sound player called

IonSound.js
which can be found here. http://ionden.com/a/plugins/ion.sound/en.html

According to the documentation, I can listen for
sound.ended
event like so:

ion.sound({
sounds: [
{name: "door_bump"},
{name: "water_droplet_2"},
{name: "water_droplet_3"}
],
ended_callback: function (sound) {
// sound ended
game.sound.soundEnded(sound);
}
});


I made a very basic wrapper on top of this.

class Sound
{
constructor(ion) {
this.ion = ion;
this.promises = {};
}

play(sound) {
if (game.settings.muted === false) {
this.ion.sound.play(sound);
}

this.promises[sound] = new Promise((accept, reject) => {

});

return this.promises[sound];
}

soundEnded(sound) {
if (this.events.hasOwnProperty(sound.name) === true) {
Promise.resolve(this.promises[sound.name])
}
}
}


Right now, when I execute the following code:

game.sound.play("level-up");


ended_callback
triggers. Then it calls
sound.soundEnded
.

The problem is, it becomes a mess like so. What I want to do instead is promisifying my Sound class so I can use it like so:

game.sound.play("level-up").then(() => {
console.log("Sound is over.");
});


In order to do it, this piece of code has to
fulfill()
my Promise that I kept on
this.promises
hash.

Promise.resolve(this.promises[sound.name]);


but it doesn't have any methods to trigger fulfill like this:

this.promises[sound.name].fulfill();


Any ideas?

Answer

Instead of keeping an array of promises in this.promises, keep an array of promise accept/reject-callbacks in this.promiseFulfil. That way you have a handle to fulfil the promise.

Here is how your class could look:

class Sound
{
    constructor(ion) {
        this.ion = ion;
        this.promiseFulfil = {};
    }

    play(sound) {
        if (game.settings.muted === false) {
            this.ion.sound.play(sound);
        }

        // Just return the promise without storing it.    
        return new Promise((accept, reject) => {
            // keep track of which function to call to fulfil promise:
            this.promiseFulfil[sound] = { accept, reject };
        });
    }

    soundEnded(sound) {
        if (this.promiseFulfil[sound]) {
            // call the appropriate promise-callback:
            this.promiseFulfil[sound].accept();
            // optionally clear this entry:
            this.promiseFulfil[sound] = undefined;
        }
    }
}