Is it possible to use await outside async function - javascript

This is my simple function in nodejs
const myFunction = async() => {
const exercises = await Exercise.find({ workoutId })
return exercises
}
const value = await myFunction()
But when I do await outside async function it throws an error
await is a reserved word
Now how do I wait for the value outside the async function? Do I need to use callback or .then? Then what is the use async and await?

You can't use await outside an async function.
one trick to 'bypass' this limit is to use async IFEE:
const myFunction = async() => {
const exercises = await Exercise.find({ workoutId })
return exercises
};
(async () => {
const value = await myFunction()
})()

Short answer to the main question: "Is it possible to use await outside async function" no.
But there's multiple ways to access the value of an async operation, for example
const myFunction = async() => {
const exercises = await Exercise.find({ workoutId })
return exercises
}
const execution = () => {
myFunction().then( ( exercises ) => {
console.log( exercises );
});
}
As async is a wrapper for Promises to access the result you need to use then and when the execution is completed that callback is fired.

Related

Curry function with the first one as an async function isn't working

I'm trying to curry a function but when the first one is async it throws the error function1(...) is not a function, however if I pass the async function as the last one it works fine.
Can anyone tell me why this is happening? and how to properly make a curry function that starts with a async function?
Thanks to anyone who take the time.
//This one is throwing the error: function1(...) is not a function
async function function1(path) {
const fetchedElement = await fetchElement(path);
//(...)
return (msg) => {
console.log(msg);
};
}
function1('somepath.html')('my message');
//This one works fine, properly returning other function
function function2(path) {
return async (msg) => {
const fetchedElement = await fetchElement(path);
//(...)
console.log(msg);
};
}
function2('somepath.html')('my message');
It depends on when the async work needs to get done. If you want the currying process to do the async work, then you can't invoke the currying function synchronously:
curryingFunction(paramA)(paramB)
^ assumes curryingFunction is synchronous
Instead, use two statements by the caller, one to await the currying, the other to invoke...
const fetch = path => new Promise(resolve => setTimeout(() => {
console.log('fetched ' + path)
resolve()
}, 1000));
async function curryingFunction(path) {
const fetchedElement = await fetch(path);
return message => {
console.log(message);
}
}
async function someCaller() {
// await to get a curried function, then invoke it
let curried = await curryingFunction('some_path');
curried('some message');
}
someCaller()
On the other hand, you might not need to do the async work in order to get the curried function. You probably don't. In that case, you can make the currying function synchronous, but have it return an async function that does the async work.
As a result, you'll get to use the fn()() syntax that you're probably used to using...
const fetch = path => new Promise(resolve => setTimeout(() => {
console.log('fetched ' + path)
resolve()
}, 1000));
function curryingFunction(path) {
return async (message) => {
const fetchedElement = await fetch(path);
console.log(message);
}
}
async function someCaller() {
// here we can use the fn()() syntax that we're accustomed to
await curryingFunction('some path')('some message')
}
someCaller()
As the first function is async You need to await it first, then call the second parameter.
//This one is throwing the error: function1(...) is not a function
async function function1(path) {
const fetchedElement = await Promise.resolve(1);
//(...)
return (msg) => {
console.log(msg);
};
}
(async () => {
try {
(await function1('somepath.html'))('my message');
} catch(e) {
console.log(e)
}
})()

an example of async/await in javascript

I am studying async and await in javascript, and a little bit confused about the execution order of the following function I wrote when I play around async and await:
const promiseA = new Promise((resolutionFunc, rejectionFunc) => {
setTimeout(() => resolutionFunc(666), 5000);
});
const test = async () => {
await promiseA.then((val) =>
console.log("asynchronous logging has val:", val)
);
};
const testTwo = () => {
test();
console.log("immediate logging");
};
testTwo();
my understand is that in function <testTwo()>, <test()> execute first, it's been called & executed, <test()> is an async function, and I have put the await in front of the promise.
why this console.log("immediate logging"); line of code get executed first?
on the other hand, if I wrote <testTwo()> like following:
const testTwo = async () => {
await test();
console.log("immediate logging");
};
everything is fine

await Promise.all not waiting despite async wrapper

Even after reading several answers to similar questions (e.g. this and that) I unfortunately still do not understand, why this code does not await the promises and hence logs ['check2'] last after the other checkpoints.
This is a minimal example using code from this guide. In the original code I need to fetch some Information from different sources before my express server can start listening.
console.log("check1");
const resolveInTwoSeconds = () => {
return new Promise((resolve) => {
setTimeout(() => resolve("check2"), 2000);
})
};
async function test() {
const asyncFunctions = [
resolveInTwoSeconds()
];
const results = await Promise.all(asyncFunctions);
console.log(results);
}
(async() => await test())();
console.log("check3");
EDIT:
Imagine "check3" to be a lot of code that is depended on the sideeffects of test().
Thus I want it to run after check2 was printed.
However I am using await here so I do not have to change or move "check3".
This line of code declares an async function and executes it:
(async() => await test())();
So far nothing waits for its result and the execution goes on to console.log("check3").
You have to explicitly wait for it:
await (async () => await test())();
Now, this won't work yet, because the top-level function is not async. Whenever you need to call await, you have to make sure it's called inside an async function. One way to do this would be to wrap everything inside another async function:
(async () => {
console.log("check1");
const resolveInTwoSeconds = () => {
return new Promise((resolve) => {
setTimeout(() => resolve("check2"), 2000);
})
};
async function test() {
const asyncFunctions = [
resolveInTwoSeconds()
];
const results = await Promise.all(asyncFunctions);
console.log(results);
}
await (async ()=> await test())();
console.log("check3");
})()
Otherwise, move your check3 into an async function you already have, as others suggested.
This should do what you want. you need the console.log to be inside the async function.
console.log("check1");
const resolveInTwoSeconds = () => {
return new Promise((resolve) => {
setTimeout(() => resolve("check2"), 2000);
})
};
async function test() {
const asyncFunctions = [
resolveInTwoSeconds()
];
const results = await Promise.all(asyncFunctions);
console.log(results);
}
(async() =>{
await test();
console.log("check3");
})();

How to merge asynchronous function's callback result

Here is the code to get some information about server.
cpu.usage()
.then(info => {
console.log(info);
});
cpu.free()
.then(info => {
console.log(info)
});
mem.info()
.then(info => {
console.log(info)
});
I want to get every result in a function.
get_resource () {
...
console.log(cpu_usage, cpu_free, mem_info);
};
How can I design it?
Thank you.
You can try to use async/await to do that:
var get_resource = async function () {
var cpu_usage = await cpu.usage();
var cpu_free = await cpu.free();
var mem_info = await mem.info();
console.log(cpu_usage, cpu_free, mem_info);
};
Or
Promise.all([cpu.usage(), cpu.free(), mem.info()]).then(function (info) {
console.log('cpu_usage:', info[0]);
console.log('cpu_free:', info[1]);
console.log('mem_info:', info[2]);
})
You can use Promise.all() as following:
let cpuUsage = cpu.usage()
let cpuFree = cpu.free()
let memInfo = mem.info()
Promise.all([cpuUsage, cpuFree, memInfo]).then((values) => {
console.log(values);
});
If you can use ES6, then you can use array destructuring while getting results:
Promise.all([cpuUsage, cpuFree, memInfo]).then(([cpuUsageResult, cpuFreeResult, memInfoResult]) => {
console.log(cpuUsageResult);
console.log(cpuFreeResult);
console.log(memInfoResult);
});
Callback Hell
This is the old scenario where you would have to call things inside one another
cpu.usage()
.then(cpu_usage => {
cpu.free()
.then(cpu_free => {
mem.info()
.then(mem_info => {
console.log(cpu_usage, cpu_free, mem_info);
});
});
});
Async Await
in this scenario you make a function that is asynchronous.
async function get_resource () {
const cpu_usage = await cpu.usage();
const cpu_free = await cpu.free();
const mem_info = await mem.info();
console.log(cpu_usage, cpu_free, mem_info);
};
The value assigned to each const in the async function is the same value that you get as an argument in the callback of the then.

How to translate Promise code to async await

I have some simple Promise in js:
let link = "https://jsonplaceholder.typicode.com/posts/1";
fetch(link)
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
... and I want to translate it to 'async await' like here:
const API_ENDPOINT = 'https://jsonplaceholder.typicode.com/posts/1';
const fetchUsers = async () => {
const response = await fetch(API_ENDPOINT);
const data = await response.json();
};
... but I don't know how involve it in 'async await' correctly. This involving gives error:
fetchUsers()
.then(response => response.json())
.then (data => console.log(data))
.catch(error => console.error(`ERROR ${error}`));
Can you help me fix this error?
const API_ENDPOINT = 'https://jsonplaceholder.typicode.com/posts/1';
const fetchUsers = async () => {
const response = await fetch(API_ENDPOINT);
const data = await response.json();
console.log(data);
};
Your code is working prefectly Just call fetchUsers() and It will print data through this line console.log(data);
You can't use await keyword outside the async type function
Read this -
An async function can contain an await expression that pauses the
execution of the async function and waits for the passed Promise's
resolution, and then resumes the async function's execution and
returns the resolved value.
Remember, the await keyword is only valid inside async functions. If
you use it outside of an async function's body, you will get a
SyntaxError.
Two problems here;
You don't return anything from your async function
You apply response.json() twice.
Just corect the code as;
const API_ENDPOINT = 'https://jsonplaceholder.typicode.com/posts/1',
fetchUsers = async () => { var response = await fetch(API_ENDPOINT);
return await response.json();
};
fetchUsers().then (data => console.log(data))
.catch(error => console.error(`ERROR ${error}`));
Async functions must be functions. So, you need to create a function to do that.
MDN says:
The async function declaration defines an asynchronous function, which returns an AsyncFunction object.
Read more about that on MDN
So:
Create a function using the async keyword
Perform your fetch call inside the function using the await keyword
Perform any other operations inside your function using the await keyword around any promise related operations (if you want)
An example below:
async function doFetch(link) {
let result = await fetch(link); // this will wait the result to be fetched
console.log(result); // this will only log the result of the fetch promise after it is resolved
let json = await result.json();
console.log(json);
}
const link = 'https://jsonplaceholder.typicode.com/posts/1';
doFetch(link);
Also, remember that when you use the await keyword, your asynchronous code will actually run synchronously, so, two sequential calls to any promises will run synchronously, like so:
async function foo() {
let bar = await fetch('https://www.google.com');
// the line below will run just _*AFTER*_ the above line is completely resolved
let baz = await fetch('https://www.facebook.com');
}

Categories