As a simple example, I'll walk through the title question. Say you want to do something, wait 4 seconds, then do something else. You naively try the following:
console.log(new Date()); setTimeout(function () { console.log(new Date()); }, 4000); console.log(new Date());
If you try that, you'll immediately notice that the console.log after the setTimeout executes immediately and does not wait 4 seconds for the setTimeout. The issue is that the setTimeout is effectively saying 'in 4 seconds, execute this content' and then moving on.
A simple way to handle this is to have the timeout body resolve a promise. Then, you can just await that promise after, and you'll get the behavior you expect. Here's a simple example of that:
async function test() { console.log(new Date()); promise = new Promise(function (resolve, reject) { setTimeout(function () { console.log(new Date()); resolve(); }, 4000); }); await promise; console.log(new Date()); }
Just wrap the setTimeout in a promise, resolve after doing the setTimeout stuff, and await before moving on. That last console.log will now execute after that setTimeout. Here is a working example of both to see this:
See the Pen await timeout demo by Robert Hamner (@rhamner) on CodePen.
For a related example...what if you want to run httprequests in a sequence instead of in parallel? Again, you naively try this and see that it doesn't work:let req1 = new XMLHttpRequest(); req1.open("GET", "https://jsonplaceholder.typicode.com/todos/1", true); req1.send(null); let req2 = new XMLHttpRequest(); req2.open("GET", "https://jsonplaceholder.typicode.com/todos/1", true); req2.send(null);
It's the same basic issue as before...nothing here tells the req2 code to wait for req1 to finish. To fix it, you can do something like this:
async function test() { let promise = new Promise(function (resolve, reject) { let req1 = new XMLHttpRequest(); req1.open("GET", "https://jsonplaceholder.typicode.com/todos/1", true); req1.onreadystatechange = function () { if (req1.readyState === 4 && req1.status === 200) { resolve(); } }; req1.send(null); }); await promise; let req2 = new XMLHttpRequest(); req2.open("GET", "https://jsonplaceholder.typicode.com/todos/1", true); req2.send(null); } test();
Now, req1 is wrapped in a promise that only resolves when req1 gets a valid response, and the req2 code comes after an await for that promise (note this is poorly written...real code would handle other responses for example). Here's an example of these:
This technique can be used to order many things in JavaScript and is really flexible and simple.
See the Pen await httprequest demo by Robert Hamner (@rhamner) on CodePen.
To see it, go to that code, turn on network recording in your browser, and run. You should see three simultaneous requests for '1', then a fourth one that comes after the third one finishes.This technique can be used to order many things in JavaScript and is really flexible and simple.
0 comments:
Post a Comment