Пропустите функцию, если время выполнения слишком велико.JavaScript - PullRequest
0 голосов
/ 23 января 2019

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

Например, у меня есть 3 функции:

function A(){
 Do something.. ..
}

function B(){
 Do something.. ..
}

function C(){
 Do something.. ..
}

A();
B();
C();

Так, например, по какой-то причине функция B имеет внутри бесконечный цикл и продолжает работать. Как я могу пропустить функцию B и перейти к функции C, если функция B выполняется слишком долго?

Я пробовал это, но, кажется, не работает:

try {
 const setTimer = setTimeOut({ 
  throw new Error("Time out!");
 },500);
 B();
 clearInterval(setTimer);
}
catch(error){
 console.warn(error);
}

Но, кажется, не работает.


Обновление 1: к вашему сведению, я не делал никаких анти-паттернов, но функция B - это что-то в NPM, и я отправлял проблемы владельцу репо. Просто попробуйте уклониться от пули, чтобы у меня было немного времени до исправления. Спасибо, ребята, что помогли мне до сих пор:)

Ответы [ 2 ]

0 голосов
/ 23 января 2019

setTimeout нельзя использовать для остановки выполнения функции

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

Остановите, проверив прошедшее время (не рекомендуется).

Решением было бы проверить, сколько времени занимает функция, поместив проверки повсюду в вашей функции.

function A(mili){
  const end = Date.now() + mili;
  for(let i = 0; i < 10000; i++){
    for(let j = 0; j < 10000; j++){
      if(Date.now() > end){
        console.log(mili + ": Halting A...");
        return;
      }
    }
  }
  
}

A(100); //halted
A(1000); //halted
A(10000); //passed

Но это не решит вашу проблему и не рекомендуется, поскольку требует, чтобы вы добавили много «проверок» в ключевые моменты, когда ваша функция может слишком долго тратить время во время выполнения.

Остановить с помощью генераторов функций

Предполагается, что вы находитесь в синхронной среде

Генераторы функций не идеальное решение, но это лучшее решение.

Требуются две простые для понимания модификации вашей исходной функции.

  1. Добавьте * к названию вашей функции
  2. Добавьте ключевое слово yield в ключевые места в вашей функции, которые могут рассматриваться как "длительное время выполнения"

Наконец, передайте функцию, которую вы хотите протестировать, в некоторой оболочке, например, метод run, представленный ниже.

function* A(){
  for(let i = 0; i < 10000; i++){
    for(let j = 0; j < 1000; j++){
       yield;
    }
  }
  return "some final value";
}

function run(gen, mili){
  const iter = gen();
  const end = Date.now() + mili;
  do {
    const {value,done} = iter.next();
    if(done) return value;
    if(end < Date.now()){
      console.log("Halted function, took longer than " + mili + " miliseconds");
      return null;
    }
  }while(true);
}

console.log("Running...");
const res1 = run(A, 1000);
const res2 = run(A, 5000);
const res3 = run(A, 100);

console.log("run(A,1000) = " + res1); //halted
console.log("run(A,5000) = " + res2); //passed
console.log("run(A,100) = " + res3); //halted
0 голосов
/ 23 января 2019

Чтобы узнать, сколько времени занимает выполнение функции, вам нужно выполнить ее и измерить. Прочитайте о проблеме остановки . Тьюринг в основном доказывает, что проблема остановки неразрешима, что означает, что нет никакого программного способа определить, является ли цикл бесконечным или, в более общем смысле, остановится ли выполнение когда-либо.

Проблема заключается в том, что даже если вы установите порог по времени выполнения вашей функции, вы не сможете завершить свою функцию извне. Таким образом, попав в бесконечный цикл, вы не сможете завершить его, если ваша функция внутренне не предполагает, что может войти в бесконечный цикл, и, таким образом, измеряет свое время выполнения и завершается, если превосходит его. Даже при таком подходе вы не сэкономите время выполнения, так как все ваши функции будут выполняться, а некоторые просто прекратят работу после того, как они превысят установленный порог. Это, конечно, также предполагает, что все методы, которые вы выполняете, написаны вами, с учетом допущений, и никакие внешние методы не используются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...