Как я могу обновить условие в функциональной оболочке, в то время как с обратным вызовом без использования eval ()? - PullRequest
0 голосов
/ 17 апреля 2019

Я хотел бы определить функцию, которая будет действовать как оператор while ( с некоторыми дополнениями, но для простоты я покажу здесь базовую оболочку ). То есть с условиями в качестве первого параметра и обратным вызовом для выполнения в каждом цикле в качестве второго.

Сначала я пришел с этой версией:

const wrappedWhile = (conditions, callback) => {
  let avoidInfinite = 0;

  while (conditions) {
    callback();
    
    if (avoidInfinite >= 10) {
      console.log('breaking while statement for avoiding infinite loop');
      break;
    }
    
    avoidInfinite++;
  }
};

let i = 0;

wrappedWhile(i < 5, () => {
  console.log('log from callback: i =', i);
  
  if (i >= 5) {
    console.log('the loop continues whereas it should stop');
  }
  
  i++;
});

Логически, ожидается остановка, когда i >= 5. Но параметр conditions является простым логическим значением в функции wrappedWhile, поэтому он всегда равен true, поскольку i было меньше, чем 5 при вызове.

Затем я придумал другую версию, где conditions оценивается на каждой итерации цикла:

const wrappedWhile = (conditions, callback) => {
  while (Function('return ' + conditions + ';')()) {
    callback();
  }
};

let i = 0;

wrappedWhile('i < 5', () => {
  console.log('log from callback: i =', i);
  i++;
});

Но, если я не ошибаюсь, Function использует для работы eval(), и все мы однажды слышали, что использование eval() не совсем безопасно для внедрения кода.

Теперь мой вопрос прост: Есть ли более безопасные альтернативы, чтобы делать то, что я хочу достичь?

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

1 Ответ

1 голос
/ 17 апреля 2019

Вы должны передать функцию как условие и вызвать ее в цикле while

const wrappedWhile = (conditions, callback) => {
  let i = 0;

  while (conditions(i)) {
    callback(i);
    
    if (i >= 10) {
      console.log('breaking while statement for avoiding infinite loop');
      break;
    }
    
    i++;
  }
};

wrappedWhile((i) => (i < 5), (iteration) => {
  console.log('log from callback: i =', iteration);
});
...