前一个完成后执行javascript函数

时间:2019-02-13 13:42:45

标签: javascript asynchronous settimeout

我有一个具有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);
}

两个函数同时执行。

5 个答案:

答案 0 :(得分:3)

有很多不同的方法,但是我建议使用这样的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();后才执行。

或者,您也可以使用callbackasync / await

答案 1 :(得分:1)

函数结束后,您可以使用回调执行其他指令:

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

答案 2 :(得分:1)

您可以使用Promise进行此操作。您必须将showElement()函数包装到一个Promise中,并在setTimeout触发后调用Promise解析程序。 然后,您的调用代码可以pipe thenshowElement(document.getElementById('formGroupSpinner'), 2000).then(() => { showElement(document.getElementById('formGroupSuccessImg'), 2000).then(() => { resetForm(); }); }); 一起使用您的诺言:

async

但是,这很快会导致回调地狱。

您可以使用async/await来避免这种情况。 您将函数标记为await,然后可以在其中使用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>
all(test[, 2] >= cummax(test[, 2]))

答案 3 :(得分:0)

最简单的方法是将第二个 showElement 更改为 4000 ,而不是 2000

这样,一个将有2秒钟的超时,另外4秒钟。

答案 4 :(得分:0)

要做出承诺链,您首先必须有一个承诺。

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 */)