How to return a promise resolved from a callback

Tags: , ,



I have an issue with my promise logic (still pretty new to JS), and I cannot find what is wrong. Looking at how hard it is for me to do what I want, I can only guess that’s it’s not the correct way to do it. I did found another way to fix it, but I am still interested if there is a way to do what I want or not.

Here are some details:

I have a MessageQueue.sendMessage() which adds the message I give to the PendingMessageCache. When it can, the MessageQueue takes the cache and sends the Message to the server.

Sometimes I need to do some stuff after the message is sent. So I added a callback, saved and invoked by the MessageQueue when it sends the message. It’s working great. The call looks basically like this:

await MessageQueue.sendMessage(myMsg, () => {markMessageAsSent()});

For one new type of message, I need to wait for the message being effectively sent because the app is completely cleaned after it.

As the sendMessage just adds the message to the cache and returns, the callback is later called but in this case it’s too late, the app was restarted.

The message is basically a lastMessage sent to the server to say that this user removed the specific application instance.

So I think that what I want would be something like this:

deleteAccount = async () => {
    const aMagicalCallback;

    // this call adds the message to the cache, 
    // and ask the MessageQueue to call aMagicalCallback when that lastMsg is sent
    await MessageQueue.sendLastMessage(lastMsg, <aMagicalCallback>);
    // return the callback which would be a promise.
    // this promise is resolved when it is resolved 
    // when the MessageQueue invokes the callback <aMagicalCallback>
    return <aMagicalCallback>;
}

what I would like this to do is basically

    // wait for the lastMessageBeingEffectively sent
    await deleteAccount();
    app.eraseEverything();
    app.restart();

Let me know if that is not clear at all. And thanks

Answer

You should return a Promise instead of using async. So you can choose when to resolve the promise, even in a nested callback function:

deleteAccount = () => new Promise(resolve => {
    MessageQueue.sendLastMessage(lastMsg, () => {
        // do your thing
        resolve();
    });
});

Then you can await it just like a regular async function

// this awaits until the resolve() above has been called
await deleteAccount();

app.eraseEverything();
app.restart();


Source: stackoverflow