How to "Await" for a Callback to Return

How to await for a callback to return?

async/await is not magic. An async function is a function that can unwrap Promises for you, so you'll need api.on() to return a Promise for that to work. Something like this:

function apiOn(event) {
return new Promise(resolve => {
api.on(event, response => resolve(response));
});
}

Then

async function test() {
return await apiOn( 'someEvent' ); // await is actually optional here
// you'd return a Promise either way.
}

But that's a lie too, because async functions also return Promises themselves, so you aren't going to actually get the value out of test(), but rather, a Promise for a value, which you can use like so:

async function whatever() {
// snip
const response = await test();
// use response here
// snip
}

How can an async function await the callback of an inner async function?

You'll want to wrap the callback in a new Promise and return the resolve or reject. This way, you can await your call to await getPublicKey() and it will not resolve until the callback is done.

async getPublicKey(): Promise<string> => {
return new Promise((resolve, reject) => {
const callback = async (err: any, key: any) => {
if (!err) {
resolve(key.result);
}
else {
reject(err);
}
};

this.web3js.currentProvider.sendAsync({
jsonrpc: '2.0',
method: 'eth_getEncryptionPublicKey',
params: [this.account],
from: this.account,
}, callback);

})
})
}

Using async/await with callback functions

findOne returns an awaitable object - so you don't need to pass a callback to it. Don't try mixing callbacks with async/await. The only way to return the value from the callback, as a result of the constructed promise is by using resolve (only available in the promise executor).

Instead, make it all async - functionally similar but far cleaner.

async findForUser(userId: string | Types.ObjectId): Promise<Achievement[]> {
const user = await UserSchema.findOne({ _id: userId });

const AchievementMap: Achievement[] = [];
user.achievements?.forEach(a => {
AchievementMap.push(a);
});
return AchievementMap;
}

How to await a callback function call in Node.js?

The solution to this question depends on operation.attempt. If it returns a promise you can simply return that promise in SendReqToServer, too. But usually async functions with callbacks don't return promises. Create your own promise:

const retry = require('retry');

async function HandleReq() {

//Some code
return await SendReqToServer();
}

async function SendReqToServer() {

return new Promise((resolve, reject) => {
operation.attempt(async (currentAttempt) => {
try {
let resp = await axios.post("http://localhost:5000/api/", data, options);
resolve(resp.data);
return resp.data;
} catch (e) {
if(operation.retry(e)) {throw e;}
}
});
});
}

Returning an object from a callback using async/await

Use Promise:

const result = await new Promise((resolve) => {
request.get(url, options, (error, response, body) => {
console.log( 'body', body );
resolve(body);
});
});

Edit:

or you can install https://github.com/request/request-promise

Wait for a callback to be called in an async method

Take a look at this:

public async Task<string> GetImportantString()
{
string importantResult = null;
using (var sph = new SemaphoreSlim(0, 1))
{
await SubscribeToEvent("some event", async (message) =>
{
importantResult = message; // When "some event" happens, callback is called and we can set importantResult
sph.Release();
});

var t = sph.WaitAsync();

if (await Task.WhenAny(t, Task.Delay(10000)) == t)
{
return importantResult;
}
}
throw new TimeoutException(); // whatever you want to do here
}

We use a SemaphoreSlim to signal when the string is set.

At that point, we await on Task.WhenAny which lets us know when either the Semaphore releases or a delay-task elapses. If the Semaphore releases, we can safely assume the string has been set and return it.

How do i wrap a callback with async await?

Include async before the function declaration and await the Promise constructor. Though note, you would essentially be adding code to the existing pattern. await converts a value to a Promise, though the code at Question already uses Promise constructor.

async function start() {
let promise = await new Promise((resolve, reject) => {
this.server = Http.createServer(app);
this.server.listen(port, () => {
resolve();
});
})
.catch(err => {throw err});

return promise
}

start()
.then(data => console.log(data))
.catch(err => console.error(err));


Related Topics



Leave a reply



Submit