Как выполнить функцию обратного вызова, когда функция восстановления работает в Javascript? - PullRequest
2 голосов
/ 13 марта 2020

Невозможно запустить функцию обратного вызова во время работы рекурсивной функции?

Это пример кода функции рекурсивной Фибоначчи и setInterval ()

'use strict';

function fibo(x) {
  if (x === 0) {
    console.info('fibo( ' + x + ' ) == 0');
    return 0;
  } else if (x === 1) {
    console.info('fibo( ' + x + ' ) == 1');
    return 1;
  }
  return fibo(x-2) + fibo(x-1);
};

fibo(10);

setInterval(() =>{console.info('hello')},10);

Исключая этот код, setInterval запускается после fibo (10) завершил свою работу.

Как отобразить журнал 'hello' во время работы fibo ()? Можно ли включить функцию обратного вызова во время работы рекурсивной функции?

1 Ответ

2 голосов
/ 13 марта 2020

Как отобразить журнал 'hello' во время работы fibo ()?

Поскольку fibo синхронно, вы не можете в обычном случае. JavaScript работает на основе потоков, обслуживающих очередь заданий. Пока выполняется одно задание, никакие другие задания не могут выполняться в этом потоке (например, те, которые поставлены в очередь setInterval для вызова обратного вызова). В realm (только глобальная среда) есть только один поток, и во всех основных средах (включая браузеры) есть только один основной поток. Вы можете создавать других, но у них есть своя собственная среда.

У вас есть пара опций:

  1. Сделать fibo асинхронным, где каждый вызов к нему планирует следующий в другом задание (например, через setTimeout).
  2. Сделайте fibo функцией генератора и несколько раз вызывайте ее для значений, перемежая эти вызовы с вашим обратным вызовом setInterval.
  3. Используйте рабочий поток.

Поскольку ваш код setInterval и ваш код fibo не предоставляют никаких данных, использование рабочего потока имеет смысл:

main.js:

'use strict';

function fibo(x) {
  if (x === 0) {
    console.info('fibo( ' + x + ' ) == 0');
    return 0;
  } else if (x === 1) {
    console.info('fibo( ' + x + ' ) == 1');
    return 1;
  }
  return fibo(x-2) + fibo(x-1);
};

new Worker("worker.js");
fibo(10);

worker.js:

setInterval(() =>{console.info('hello')},10);

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

...