I try to run a script in the chrome debugger tools. Within the script I would like to wait (e.g. for a button after a rendered animation). How can I do this? I found some solutions like that:
async function test () {
console.log('1');
await setTimeout(function() {
console.log('2');
}, 3000);
console.log('3');
}
I expected to print 1, 2 and after three seconds 3. But the result is 1,3 and then 2 after three seconds.
I would like to do it for several sequential actions.
Any idea how I can do this?
I try to run a script in the chrome debugger tools. Within the script I would like to wait (e.g. for a button after a rendered animation). How can I do this? I found some solutions like that:
async function test () {
console.log('1');
await setTimeout(function() {
console.log('2');
}, 3000);
console.log('3');
}
I expected to print 1, 2 and after three seconds 3. But the result is 1,3 and then 2 after three seconds.
I would like to do it for several sequential actions.
Any idea how I can do this?
Share Improve this question asked Nov 2, 2019 at 0:43 dafnadafna 9733 gold badges11 silver badges23 bronze badges3 Answers
Reset to default 3You cannot await
the result of the setTimeout
function because it is not a Promise
. To do what you want to do, you could create a Promise
that resolve after 3 seconds, here is an example:
async function test() {
console.log('1');
console.log('2');
await new Promise(resolve => {
setTimeout(resolve, 3000);
});
console.log('3');
}
test();
From your description it seems like you want to access some DOM elements when they bee available, there is MutationObserver for that, here is an example:
const parent = document.querySelector('#parent');
setTimeout(() => {
const button = document.createElement('button');
button.textContent = 'BUTTON';
button.id = 'targetBtn';
parent.appendChild(button);
}, 2000);
const observer = new MutationObserver((mutationList) => {
mutationList.forEach((mutationRecord) => {
if (mutationRecord.addedNodes && mutationRecord.addedNodes.length) {
const btn = [...mutationRecord.addedNodes].find(n => n.matches && n.matches('#targetBtn'));
if (btn) {
console.log('Button #' + btn.id + ' was found');
}
}
});
});
observer.observe(parent, {
childList: true
});
<div id="parent">
</div>
What this does is to monitor #parent
element's child list to see when the #targetBtn
element is added.
This is kind of overkill, a better solution will be to monitor events that will cause the targeted element to bee available.
I think you're asking two different questions. One asking how to wait for the element to be the DOM and another question about how asynchronous actions work in JavaScript.
For waiting for an element to be displayed the DOM, the simplest solution (in my opinion) would be to create a while
loop and break once the element exists:
// NOTE: this code isn't tested nor I have tried to see if it works
let elem = document.querySelector('.someSelector');
while(!elem) {
elem = document.querySelector('.someSelector');
}
// do something else when the element shows
Keep in mind that this could cause memory leak issues.
I expected to print 1, 2 and after three seconds 3.
Your expectation is wrong. The way setTimeout
works is that it will add your callback function to a separate stack and call it after the amount of milliseconds you define. If you wanted to show three after 3 seconds you would have to do:
function test() {
console.log('1');
console.log('2');
setTimeout(function() {
console.log('3');
}, 3000);
}
Or using async/await
async function test() {
console.log('1');
console.log('2');
await new Promise(resolve => {
setTimeout(resolve, 3000);
});
console.log('3');
}
As mentioned by others, await
waits for a promise to get resolved or rejected. setTimeout
doesn’t return a Promise and hence the execution moves to the next line which outputs 3.
Helpful read: https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Statements/async_function
In terms of waiting for an element, it depends on what framework you are using. For plain JavaScript, you could trigger a custom event in addition to making the button visible. React has ways where you can trigger actions based on certain prop changes.