簡體   English   中英

前一個完成后執行javascript函數

[英]Execute javascript function after previous one finishes

我有一個具有setTimeout的函數“ showElement”。 如何使對“ btnSend”的eventListener中的函數的調用在另一個之后立即執行?

我嘗試使用.then(),但是沒有用。

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);
}

這兩個功能同時執行。

有很多不同的方法,但是我建議使用這樣的Promise:

 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); }); } 

基本上, .then()之后的函數僅在調用resolve();之后才執行resolve();

或者,您也可以使用回調async / await

您可以在函數結束后使用回調函數執行其他指令:

//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();
        });  
    }
}); 

您可以使用Promise做到這一點。 您必須將showElement()函數包裝到showElement()並在setTimeout觸發后調用showElement()解析器。 然后調用代碼可以pipe你的承諾一起then

showElement(document.getElementById('formGroupSpinner'), 2000).then(() => {
    showElement(document.getElementById('formGroupSuccessImg'), 2000).then(() => {
        resetForm();
    });
});

但是,這很快導致回調地獄。

您可以使用async/await避免這種情況。 您可以將函數標記為async ,然后可以在其中使用await等待promise解析,然后繼續執行下一個:

await showElement(document.getElementById('formGroupSpinner'), 2000);
await showElement(document.getElementById('formGroupSuccessImg'), 2000);
resetForm();

這是一個工作示例:

 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> 

執行所需操作的最簡單方法是將第二個showElement更改為4000而不是2000

這樣,一個將有2秒鍾的超時時間,其他4秒鍾。

要做出承諾鏈,您首先必須有一個承諾。

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);
  }
}

然后您可以使用showElement().then(/*something here */)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM