admin管理员组文章数量:1405553
I have the function "showElement" that has a setTimeout. How can I make that the calls to the function in the eventListener of the 'btnSend' execute one right after the other one?
I tried with .then() but didn't work.
document.getElementById('btnSend').addEventListener('click', e => {
e.preventDefault();
result = validateInputs(email, subject, message);
if(result) {
showElement(document.getElementById('formGroupSpinner'), 2000);
showElement(document.getElementById('formGroupSuccessImg'), 2000);
resetForm();
}
});
//expects an html element and a number representing miliseconds. Shows the html element for that amount of time.
function showElement(element, mSeconds) {
element.classList.remove('d-none');
element.classList.add('d-block');
setTimeout( () => {
element.classList.remove('d-block');
element.classList.add('d-none');
}, mSeconds);
}
Both functions execute at the same time.
I have the function "showElement" that has a setTimeout. How can I make that the calls to the function in the eventListener of the 'btnSend' execute one right after the other one?
I tried with .then() but didn't work.
document.getElementById('btnSend').addEventListener('click', e => {
e.preventDefault();
result = validateInputs(email, subject, message);
if(result) {
showElement(document.getElementById('formGroupSpinner'), 2000);
showElement(document.getElementById('formGroupSuccessImg'), 2000);
resetForm();
}
});
//expects an html element and a number representing miliseconds. Shows the html element for that amount of time.
function showElement(element, mSeconds) {
element.classList.remove('d-none');
element.classList.add('d-block');
setTimeout( () => {
element.classList.remove('d-block');
element.classList.add('d-none');
}, mSeconds);
}
Both functions execute at the same time.
Share edited Feb 13, 2019 at 13:49 jo_va 14k3 gold badges25 silver badges49 bronze badges asked Feb 13, 2019 at 13:42 Floro VarelaFloro Varela 691 silver badge9 bronze badges 4- 2 Hello Floro, you seems new to JS, look for JavaScript callbacks. – Mehdi Benmoha Commented Feb 13, 2019 at 13:46
- Please add your HTML too :) – jo_va Commented Feb 13, 2019 at 13:47
- 2 @jo_va not relevant – Adelin Commented Feb 13, 2019 at 13:47
-
1
To use
then
, you need to create and return a promise – Bergi Commented Feb 13, 2019 at 13:47
5 Answers
Reset to default 3There's many different approaches to this but I would suggest using a Promise like this:
document.getElementById('btnSend').addEventListener('click', e => {
e.preventDefault();
var result = validateInputs(email, subject, message);
if(result){
showElement(document.getElementById('formGroupSpinner'), 2000).then(()=>{
return showElement(document.getElementById('formGroupSuccessImg'), 2000);
}).then(()=>{
resetForm();
});
}
});
//expects an html element and a number representing miliseconds. Shows the html element for that amount of time.
function showElement(element, mSeconds) {
return new Promise((resolve, reject) => {
element.classList.remove('d-none');
element.classList.add('d-block');
setTimeout( () => {
element.classList.remove('d-block');
element.classList.add('d-none');
resolve();
}, mSeconds);
});
}
Basically, the function after the .then()
only gets executed once you called the resolve();
.
Alternatively you could also use a callback or async / await.
you could use a callback to execute other instructions after the function has ended:
//First you add a param "callback" to the function
function showElement(element, mSeconds, callback) {
element.classList.remove('d-none');
element.classList.add('d-block');
setTimeout( () => {
element.classList.remove('d-block');
element.classList.add('d-none');
//Then you ask if the callback function is present and call it
if(callback && typeof callback === "function") callback();
}, mSeconds);
}
//Then use it in your event like this:
document.getElementById('btnSend').addEventListener('click', e => {
e.preventDefault();
result = validateInputs(email, subject, message);
if(result) {
showElement(document.getElementById('formGroupSpinner'), 2000, () => {
showElement(document.getElementById('formGroupSuccessImg'), 2000);
resetForm();
});
}
});
You can do this by using Promise
. You have to wrap your showElement()
function into a promise and call the promise resolver once setTimeout
fires.
Then your calling code can pipe
your the promises together with then
:
showElement(document.getElementById('formGroupSpinner'), 2000).then(() => {
showElement(document.getElementById('formGroupSuccessImg'), 2000).then(() => {
resetForm();
});
});
However, this quickly leads to callback hell.
You can avoid this by using async/await
.
You mark your function as async
, then you can use await
within it to wait for the promises to resolve before continuing to the next one:
await showElement(document.getElementById('formGroupSpinner'), 2000);
await showElement(document.getElementById('formGroupSuccessImg'), 2000);
resetForm();
Here is a working demo:
document.getElementById('btnSend').addEventListener('click', async e => {
e.preventDefault();
await showElement(document.getElementById('formGroupSpinner'), 2000);
await showElement(document.getElementById('formGroupSuccessImg'), 2000);
});
function showElement(element, mSeconds) {
return new Promise((resolve, reject) => {
element.classList.remove('d-none');
element.classList.add('d-block');
setTimeout(() => {
element.classList.remove('d-block');
element.classList.add('d-none');
resolve();
}, mSeconds);
});
}
.d-none {
display: none;
}
.d-block {
display: block;
}
<button id="btnSend">Send</button>
<div id="formGroupSpinner" class="d-none">Spinner</div>
<div id="formGroupSuccessImg" class="d-none">Success image</div>
The simplest way to do what you want is simply changing the second showElement to 4000 instead of 2000.
That way one will have a timeout of 2 seconds and the other 4 seconds.
To make a promise chain, you first have to have a promise.
function showElement(element, mSeconds) {
return new Promise(function(resolve,reject){
element.classList.remove('d-none');
element.classList.add('d-block');
setTimeout( () => {
element.classList.remove('d-block');
element.classList.add('d-none');
resolve();
}, mSeconds);
}
}
Then you can use showElement().then(/*something here */)
本文标签: asynchronousExecute javascript function after previous one finishesStack Overflow
版权声明:本文标题:asynchronous - Execute javascript function after previous one finishes - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744916735a2632039.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论