Как вы можете запустить команду броска через определенное время?

#node.js

#node.js

Вопрос:

Проблема: вызывается библиотечная функция, которая иногда не работает. Если эта функция не работает, иногда случается, что она не возвращает сообщение об ошибке, а застревает в бесконечном цикле.

Идея: Моей идеей сейчас было бы использовать таймер, который выполняет команду throw через заданное время, если функция не была успешно завершена ранее. Если функция была успешно завершена, до истечения таймера таймер следует просто закрыть.

Не рабочий пример кода:

 var errorCounter = 0;
async function a(m) {
  try {
    var myVar = setTimeout(function () {
      throw console.log('Error');
    }, 60000);
    await libraryFunction(m);
    clearTimeout(myVar);
  } catch {
    errorCounter  ;
    console.log(errorCounter);
  }
}
  

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

1. Если await libraryFunction(m) произойдет ошибка, это будет передано в блок catch, поэтому вам не нужен какой-либо тайм-аут для этого, вот почему у вас есть try catch

2. вы не можете выйти из бесконечного цикла блокировки (например while(true){} ), потому что ваша функция тайм-аута не выполняется. Вы можете исправить модуль или использовать child_process для изоляции выполнения

Ответ №1:

Вы могли бы использовать Promise.race для имитации тайм-аута (поиграйте с числовыми значениями ниже):

 const timeout = new Promise((_, reject) => {
  setTimeout(() => reject(new Error('timeout')), 1000);
});

const task = new Promise((resolve, _) => {
  setTimeout(() => resolve('done'), 2000);
});


Promise.race([timeout, task])
  .then((result) => { console.log(result); })
  .catch((err) => { console.log(err.message); });  

Итак, в вашем случае это выглядело бы примерно так:

 const timeout = new Promise((_, reject) => {
  setTimeout(() => reject(new Error('timeout')), 60 * 1000);
});

var errorCounter = 0;
function a(m) {
  Promise.race([timeout, libraryFunction(m)])
    .then((res) => { console.log(res); })
    .catch((err) => {
        errorCounter  ;
        console.log(errorCounter);
    });
}
  

Ответ №2:

Вы можете использовать Promise.race для такого рода вещей:

 const MAX_WAIT_TIME = 500

const libFn = new Promise((resolve, reject) => {
  setTimeout(() => resolve('success'), Math.random() * 1000);
})

const throwFn = new Promise((resolve, reject) => {
  setTimeout(() => reject('failure'), MAX_WAIT_TIME);
})

;(async () => {
    const result = await Promise.race([libFn, throwFn])

    console.log('done') // this line won't execute if the timeout is reached
})()