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
How to Update State.Item[1] in State Using Setstate
5Xx or 4Xx Error with "No 'Access-Control-Allow-Origin' Header Is Present"
How to Efficiently Randomly Select Array Item Without Repeats
Recursively Looping Through an Object to Build a Property List
How to Mock an Es6 Module Import Using Jest
Expression Inside Switch Case Statement
How to Detect Whether an Iframe Is Loaded
Get Value of Input Field Inside an Iframe
How to Add Drop-Down List (<Select>) Programmatically
Anchor Jumping by Using JavaScript
Is It Safe to Store a Jwt in Localstorage with Reactjs
How to Chop/Slice/Trim Off Last Character in String Using JavaScript
Why Does Usestate Cause the Component to Render Twice on Each Update
Event When Window.Location.Href Changes
Javascript/Jquery to Download File via Post with JSON Data
Filter Array of Objects with Another Array of Objects