Я начну с причины, по которой вам нужно это решение.
Причина в том, что у вас нет ссылки на asyn c задачу , и вам нужно, чтобы ваше тестовое утверждение запускалось после задачи asyn c. Если он у вас был, вы можете просто await
на нем, это гарантирует, что ваше тестовое утверждение будет выполняться после задачи asyn c. (в вашем случае это ReactDOM.unmountComponentAtNode
)
В вашем примере задача asyn c находится внутри componentDidMount
, которая реагирует на вызовы, поэтому у вас нет ссылки на задачу asyn c.
Обычно простая реализация flushPromises
будет выглядеть так:
const flushPromises = () => new Promise(resolve => setImmediate(resolve));
Эта реализация основана на том факте, что операции asyn c в javascript основаны на задаче queue (javascript имеет несколько типов очередей для асинхронных c задач). В частности, обещания помещаются в очередь микрозадач. Каждый раз, когда операция asyn c (например, http-запрос) завершает выполнение задачи asyn c из очереди и выполняется.
setImmediate
- это метод, который получает обратный вызов и сохраняет его на Immediates Queue
и будет вызван в следующей итерации события l oop. Этот Immediates Queue
проверяется после очереди микрозадач (которая содержит обещания).
Давайте проанализируем код, мы создаем новое обещание, которое ставится в очередь на end из Micro-task queue
, это resolve
будет вызываться на следующей итерации события l oop, что означает, что оно будет разрешено после всех обещаний, которые уже поставлены в очередь.
Надеюсь, это объяснение поможет.
Обратите внимание , что если внутри задачи asyn c вы поставите в очередь новое обещание, оно попадет в очередь в конце, это означает, что обещание это flushPromises
return не будет выполняться после него.
Несколько сообщений / видео для получения дополнительной информации:
- https://blog.insiderattack.net/promises-next-ticks-and-immediates-nodejs-event-loop-part-3-9226cbe7a6aa
- https://www.youtube.com/watch?v=8aGhZQkoFbQ
- https://www.youtube.com/watch?v=cCOL7MC4Pl0