Определить, когда вся асинхронная работа, инициированная функцией, завершена - PullRequest
0 голосов
/ 29 марта 2019

Мне нужно знать, когда вся работа, инициированная вызовом функции, завершена.

У меня есть функция, которая принимает другую функцию в качестве параметра и вызывает эту функцию:

function outer(inner) {
   inner()
}

Внутренняя функция может инициировать некоторое асинхронное поведение:

function inner() {
   new Promise(...)
   new Promise(...)
   new Promise(...)
   requestAnimationFrame(...)
   requestAnimationFrame(...)
}

Я знаю, как работает Promise.all. Но для Promise.all вам нужно передать массив обещаний. Я хочу, чтобы моя функция не знала деталей того, что происходит внутри внутренней функции. Поскольку javascript обрабатывает много асинхронного поведения с обратными вызовами вместо обещаний, Promise.all не может обрабатывать все случаи асинхронной работы.

Из области действия внешней функции, есть ли способ определить, завершена ли асинхронная и синхронная работа внутренней функции, и применить ли это поведение к любой функции, которую я передаю в outer?

function outer(inner) {
   inner.allWorkComplete(() => ...do more work)
   inner();
}

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

Это просто анти-паттерн в javascript?

1 Ответ

3 голосов
/ 29 марта 2019

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

Это невозможно [1] .
Внутренняя функция должна сотрудничать и сообщать вам, когда она завершена - обычно она делает это, возвращая соответствующее обещание.

1: По крайней мере, без особых усилий. Вам нужно будет контролировать всю среду, чтобы вы могли определить, когда вызывается любой асинхронный примитив.

Это просто анти-паттерн в javascript?

Да. Функция, которая выполняет любую асинхронную работу, должна либо сама обрабатывать завершение (если оно не интересно кому-либо еще), либо предоставлять способ прослушивания.

В вашем примере это означает создание обещаний для requestAnimationFrame вызовов , а затем объединение всех обещаний с Promise.all для возврата обещания, которое завершается, когда ваша внутренняя функция завершает выполнение своих задач:

function inner() {
  return Promise.all([
    new Promise(...),
    new Promise(...),
    new Promise(...),
    new Promise(resolve => {
      requestAnimationFrame(() => {
        ...
        resolve();
      })
    }),
    new Promise(resolve => {
      requestAnimationFrame(() => {
        ...
        resolve();
      })
    }),
  ]);
}

(Отказ от ответственности: вышеприведенный код не очень хороший код обещания - вы не должны использовать new Promise слишком часто, только в вспомогательных функциях, которые оборачивают определенный асинхронный вызов, но больше ничего не делают - но должны дать вам представление о том, как обещания можно использовать здесь)

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