I am trying to learn the concepts of async/await in javascript. I tried a simple code, to wait for a create post function to finish before calling the getPosts function, but the newly created post is not showing up. This is what I have tried out.
const posts = [{ title: "Post One", body: "This is post one" }, { title: "Post Two", body: "This is post two" } ] const newpost = { title: "Post Three", body: "This is post three" } function getPosts() { setTimeout(() => { let output = ''; posts.forEach((post, index) => { output += `<li>${post.title} : ${post.body}</li>`; }); document.body.innerHTML = output; }, 1000); } function createPost(post) { setTimeout(() => { posts.push(post); }, 2000); } async function init() { await createPost(newpost); getPosts(); } init();
Can anyone point out what I am doing wrong?
createPost should return promise like below
function createPost(post) {
return new Promise((resolve,reject)=> {
setTimeout(() => {
posts.push(post);
resolve();
}, 2000);
});
}
The problem is that createPost
doesn't return a promise.
You can either return a promise manually:
function createPost(post) {
return new Promise((resolve) => {
setTimeout(() => {
posts.push(post);
resolve();
}, 2000);
});
}
But who want's to create promises by hand 😉? And since you want to practice with async functions, have createPost
be an async function by itself.
I'm also extracting the setTimeout
calls to a small wait
async utility function:
const posts = [{ title: "Post One", body: "This is post one" }, { title: "Post Two", body: "This is post two" } ] const newpost = { title: "Post Three", body: "This is post three" } const sleep = time => new Promise(resolve => setTimeout(resolve, time)); async function getPosts() { await sleep(1000); let output = ''; posts.forEach((post, index) => { output += `<li>${post.title} : ${post.body}</li>`; }); document.body.innerHTML = output; } async function createPost(post) { await sleep(2000); posts.push(post); } async function init() { await createPost(newpost); getPosts(); } init();
May I know why you're using setTimeout()
function? removing the setTimeout()
makes the code just work fine
const posts = [{
title: "Post One",
body: "This is post one"
},
{
title: "Post Two",
body: "This is post two"
}
]
const newpost = {
title: "Post Three",
body: "This is post three"
}
function getPosts() {
let output = '';
posts.forEach((post, index) => {
output += `<li>${post.title} : ${post.body}</li>`;
});
document.body.innerHTML = output;
}
function createPost(post) {
posts.push(post);
}
async function init() {
await createPost(newpost);
getPosts();
}
init();
Here is the working code pen: Code Pen Link
createPost should return a promise so the function should be like that
function createPost(post) {
return new Promise( resolve =>
setTimeout(() => {
posts.push(post);
resolve()
}, 2000);
});
}
The await command expects the calling function to return a promise. Such a function usually execute an asynchronous command and resolves the promise when the command is successful.
var posts = []; function createPost(post) { return new Promise(function(resolve, reject){ setTimeout(() => { posts.push(post); resolve(); //<- resolved the promise here }, 2000); }) } async function testAsync() { await createPost('a post'); console.log(posts) } testAsync();
In this case, although Array.push() doesn't do any async operation, you call it via setTimeout
to do it in an async fashion.
Async/await only works with promises, so you need to wrap whatever code you have in createPost()
in a promise, return it and then resolve it to indicate that it doesn't have to be awaited anymore and the code can continue executing. I made a tiny example from your code where you can see how it works:
function getPosts(){ setTimeout(()=>{ console.log( "get posts" ); }, 1000); } function createPost(post){ return new Promise( res => { setTimeout(()=>{ console.log( "post created" ); res(); }, 2000); } ); } async function init(){ await createPost(); getPosts(); } init();
createPost is not any async function, await will listen only to promise and async function, to be able to await that kind of setTimeout, and to apply ur intent, u need promise with done method to tell Nodejs to end listening
function createPost(post) {
return new Promise(done){
setTimeout(() => {
posts.push(post);
done()
}, 2000);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.