Как вызвать clearTimeout и при этом запустить функцию setTimeout?

#javascript

#javascript

Вопрос:

Вот мой код:

 let delayTimeout = null;
const delayExecution = mls => {
    console.log('Delaying for', mls);
    return new Promise(resolve => {
        delayTimeout = setTimeout(() => resolve('ok'), mls);
    })
}

const main = async () => {
    axios.post('URL', {data})
             .then(response => {
                 if(response passes some condition){
                     clearTimeout(delayTimeout);
                 }
             })

   const res = await delayExecution(30000)
   console.log("DONE!")
}

main();
  

После вызова axios я могу захотеть завершить работу delayExecution , очистив тайм-аут внутри него. Как мне выполнить clearTimeout внутри моей delayExecution функции, но при этом разрешить обещание?

По сути, я пытаюсь закончить delayExecution раньше времени, но все же разрешаю обещание внутри него.

Комментарии:

1. Я действительно не понимаю, что вы пытаетесь сделать. Если вы не хотите сбрасывать время ожидания — потому что вы хотите, чтобы функция все равно выполнялась через 10 секунд, независимо от того, — тогда просто не вызывайте clearTimeout .

2. В зависимости от /* Seome logic here */ того, что я могу захотеть, чтобы функция выполнялась до истечения 10 секунд.

3. Итак, вы хотите условно изменить продолжительность тайм-аута? Тогда почему бы просто не установить переменную, скажем duration , в соответствии с любой необходимой вам логикой, а затем просто выполнить setTimeout(doneFunc, duration) в конце? (Возможно, я все еще не понимаю ваших требований.)

4. Дело не в том, что я хочу условно изменить продолжительность тайм-аута, а скорее при некоторых условиях я хочу setTimeout , чтобы функция завершилась раньше, и в этом случае я все равно хочу doneFunc , чтобы функция выполнялась.

5. ваша функция setTimeout точно предназначена для выполнения вашей doneFunc функции после задержки. если вы хотите, чтобы она запускалась раньше, не используйте setTimeout

Ответ №1:

Основываясь на вашей правке, я просто оставлю другой ответ. Обратите внимание, что я не тестировал это, мой разум в настоящее время сосредоточен на моем коде, который я пишу вместе с этим, хе-хе

 let delayTimeout = null;
let resolveHandler = null;
const delayExecution = mls => {
    console.log('Delaying for', mls);
    return new Promise(resolve => {
        resolveHandler = resolve;
        delayTimeout = setTimeout(() => resolve('ok'), mls);
    })
}

const main = async () => {
    axios.post('URL', {data})
             .then(response => {
                 if(response passes some condition){
                     resolveHandler('ok');
                     clearTimeout(delayTimeout);
                 }
             })

   const res = await delayExecution(30000)
   console.log("DONE!")
}

main();
  

Идея состоит в том, чтобы просто назначить функцию resolve другой вспомогательной переменной, которую затем можно использовать в другом месте 🙂

Комментарии:

1. Да, сэр!! Работает как шарм. Спасибо.

2. Рад помочь, приятель 🙂 Добавьте меня в linkedin, мы сможем поддерживать связь

Ответ №2:

В doneFunc должен быть clearTimeout, поэтому после завершения функции время ожидания сбрасывается.

Кроме того, для первого параметра setTimeout вы можете просто передать имя функции.

На самом деле для тайм-аута вам не нужен clearTimeout, поскольку он будет запущен только ОДИН раз по сравнению с интервалом, который продолжает выполняться.

 const doneFunc = () => {console.log('Finished job');clearTimeout(f);}

const f = setTimeout(doneFunc, 100);  

Комментарии:

1. Я понимаю, что он будет выполняться только один раз, но при определенных условиях я хочу, чтобы один запуск завершился раньше, и в этом случае я хочу doneFunc , чтобы он все еще срабатывал.

Ответ №3:

Если вы хотите запустить функцию независимо от времени ожидания, просто объявите функцию вне ее, а затем вызывайте ее, когда захотите. Вы выполнили большую часть кода

 const doneFunc = () => console.log('Finished job');

const f = setTimeout(() => doneFunc(), 10000);

/* Seome logic here */

if (condition to run before timeout) {
  clearTimeout(f);
 doneFunc();

}

/* end of logic */
  

Комментарии:

1. Это похоже на решение здесь. С возможным удалением окончательного clearTimeout.

2. Это отличный момент. Проблема, конечно, в том, что функцию doneFunc не так просто запустить напрямую. Приведенный мной код очень упрощен для краткости. В рабочей среде моя функция setTimeout фактически выполняет разрешение на обещание, и я не уверен, как вызвать ее напрямую таким образом. Я должен был лучше объяснить свои требования. Итак, я собираюсь немного изменить вопрос.

Ответ №4:

Я представлял, что :

 const runOnDelay = function( fct, delay )
        {
        let obj    = {}
          , isDone = false
          , refTim = setTimeout(()=>
              {
              isDone = true
              fct()
              }, delay)
          ;
        obj.stop = () =>
          { 
          clearTimeout(refTim)
          if (!isDone)
            fct()
          isDone = true
          }
        return obj
        }
  

использование:

 const doneFunc = () => console.log('Finished job')

let myBoy = runOnDelay(doneFunc, 1000)

 //...

myBoy.stop()
  

Комментарии:

1. На самом деле это действительно аккуратный фрагмент кода. Слишком много работы для меня, чтобы переписать мою текущую логику вокруг нее, но я, без сомнения, буду использовать ее в другом месте моего приложения.