I'm trying to make an async function using fetch and then running it in order using await promise.all() and this is the code I'm using(Nodejs18):
let ids = [164838, 793838]
async función download(ids){
//Función code.......
}
await Promise.all(
ids.map(element => download(element))
)
What I'm trying to achieve is that the await promise.all() works without having to put it in an asynchronous function or change the file extension from .js to .mjs
Without changing to modules you can use the previously common method of an immediately invoked function by wrapping you code in a function and then running it.......
let ids = [164838, 793838];
async función download(ids){
//Función code.......
}
(async ()=>{
await Promise.all(
ids.map(element => download(element))
})();
Note the () at the end of the code. That calls the function that has just been created.
Related
I don't really know when/how to use async & await. For example I have this function that returns a promise:
async function fn1(){
return await fetch('localhost:3000')
}
Now I have two options:
use .then
fn1.then((result) => {
console.log(result)
})
use await
const data = await fn1()
console.log(data)
I'd prefer the second approach but this would make me wrap it inside an async function which I have to await or use .then to use it.
I've seen some tutorials that use async/await and .then at the same time but from what I can tell it's not good practice.
I create common function that will be called several different times and that function is async/await type.
const storeData = async () => {
await User.create({name: "Test 123"})
}
Now if I want to call function storeData in many different functions asynchronously, do I call it with await in a front of it (option 1 bellow) or since it has async await inside of it, will be run as async function and there is no need for await in front (option 2 bellow)?
(Note: I could do workaround and make storeData to return a new Promise and then do the things inside the promise and be sure that await will really matters.)
Option 1.
async dummy1() {
await storeData();
...rest of thte code
}
Option 2.
async dummy2() {
storeData();
...rest of the code
}
In javascript, all asynchronous functions are identical to a regular function that returns a promise. The async is just syntactic sugar. So, if you use await before the function call, the function call will block execution, and if you don't use await then it'll run asynchronously, like you desire.
Read more here.
I am trying to figure out how to call multiple methods with 1 button click synchronously. My first function is an AJAX call. So it's naturally not synchronous. To solve that issue I have used async-await. Async-await is waiting inside the same function, but not on the other functions that are being called.
I am using Stimulus.js to create classes, but general answer is enough for me: https://stimulusjs.org/
This is what my code looks like:
Button: onClick:
classA#methodA classB#methodB
in class A
async methodA(event){
const response = await axios.post('/url', { data }, options);
const data = await response.json();
doSomething()
}
in class B
methodB(){
updateThings()
}
So what I want to achieve is classA#methodA classB#methodB be called synchronously. But methodA is not waiting for methodB even though methodA is not compete. And even when I am using async await on methodA.
Any idea on how I can solve this issue?
Creating a wrapper method and calling them doesn't seem possible because of the way Stimulus.js works.
In your button click, you should have something like that:
async () => {
await methodA();
await methodB();
}
And also, the both methods should have the async mark:
async methodA(event){
const response = await axios.post('/url', { data }, options);
const data = await response.json();
doSomething()
}
async methodB(){
updateThings()
}
As your methodA is async, the main call to this method by default won't wait it to finish before executing the next lines. So you should explicitly say await methodA().
Check it out:
Understanding async await in javascript
At the start of the Puppeteer tutorial, it says to do this:
const puppeteer = require('puppeteer');
(async () =>
{
await page.goto('https://example.com');
const browser = await puppeteer.launch();
const page = await browser.newPage();
await browser.close();
})();
This seems odd to me as the whole thing is wrapped inside an asynchronous function. What if I want to wait until this finishes to continue?
Edit - Why this seems odd to me:
What if all my code relied on the browser, i.e., there is nothing I can do outside this async function. Then my code would look like this:
//nothing up here
(async () =>
{
//EVERYTHING is in here
})();
//nothing down here
This seems weird because I might as well do everything synchronously instead of wrapping my entire program in an async function.
Reason for the async function
You need to wrap the code containing await instructions inside an async function for backwards compatibility reasons. Before ES7, you could use the word await as variable or function name, meaning this was valid code:
var await = 123;
console.log(await);
To not mess with existing code, the await keyword only works inside of async functions, meaning to write code like await page.goto(..) you have to put it inside an async function like the one you are using.
Waiting for the code to finish
To wait until the code has finished, you can just continue after the last await statement like this:
(async () => {
// ...
await browser.close();
// continue with more code
})();
Very straightforward question, I know when I write an async function like this:
const res = (async () => 'hello')();
console.log(await res);
It should log: 'hello'
But, lets say I want to timeout the result inside my async function, I would have to create a new Promise so I can wrap the timeout callback in it, like this:
const res = (async () =>
new Promise(resolve =>
setTimeout(
() => resolve('hello'), 1000
)
)
)();
console.log(await res);
Well, if async already returns a promise, why should I need to create a new Promise inside a function that is already a promise, to do something as simple as this?
Am I missing something or it is indeed designed to be this way?
Wouldn't it be better if I could just do something like this in a native way? Is it even possible?
For example:
const res = (async () =>
setTimeout(
() => resolve('hello'), 1000
)
)();
console.log(await res);
Generally speaking new Promise is meant for legacy callbacks,. And ideally you want to prevent using them as much as possible.
So in your example your using a setTimeout, and then resolving the string hello. Instead of doing this, it would make more sense to create a delay function, that you could use again then just return "hello"
eg.
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
async function test() {
const res = (async () => {
await delay(1000);
return "hello";
})();
console.log(await res);
}
test();
Ultimately you need to convert a 'callback style' function into a promise, so you can't really get around making that promise. If you think this is a bit ugly, I would suggest using or building a utility function that does this for you.
Aside: unless you use await in a function, there's not really a good reason to mark it as async. This is better:
const res = new Promise(resolve =>
setTimeout(
() => resolve('hello'),
1000
)
);
console.log(await res);
I think a good way to think about async/await is that it makes certain promise-patterns easier to write, but not everything you can do with a plain promise can also be done with async/await. async/await makes a common pattern (MUCH) more legible.
Well, if async already returns a promise, why should I need to create a new Promise inside a function that is already a promise, to do something as simple as this?
An async function has three features:
It creates a promise
The promise resolves with the return value
You can use await inside it
This makes it an excellent tool to manage other functions which return promises, as it lets you use await and write code that doesn't use lots and lots of callbacks.
It doesn't make it a universal tool for replacing all other uses of Promise.
You still need one for this.
For example:
const res = (async () =>
setTimeout(
() => resolve('hello'), 1000
)
)();
console.log(await res);
If this worked, then the resolve function would be springing out of nowhere, and the return value wouldn't be the value the function resolved as.
It would lose one of the benefits of async functions.
JavaScript is a big toolbox. Different tools are suited to different jobs.