刷新承诺队列?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了刷新承诺队列?相关的知识,希望对你有一定的参考价值。
[使用Jest编写测试时,安装组件后,异步模拟的Axios请求导致了setState()
调用。这导致在测试运行期间控制台输出。
it('renders without crashing', () => {
const mockAxios = new MockAdapter(axios);
mockAxios.onGet(logsURL).reply(200, [...axios_logs_simple]);
const div = document.createElement('div');
ReactDOM.render(<Logs />, div);
ReactDOM.unmountComponentAtNode(div);
});
并且在<Logs>
组件中:
componentDidMount() {
axios.get(apiURL).then(response => {
this.setState({data: response.data});
});
}
我找到了显示解决方案的blog post,但我不知道它如何做有用的事情:
it('renders without crashing', async () => { //<-- async added here
const mockAxios = new MockAdapter(axios);
mockAxios.onGet(logsURL).reply(200, [...axios_logs_simple]);
const div = document.createElement('div');
ReactDOM.render(<Logs />, div);
await flushPromises(); //<-- and this line here.
ReactDOM.unmountComponentAtNode(div);
});
const flushPromises = () => new Promise(resolve => setImmediate(resolve));
据我所知,它创造了一个新的诺言,可以立即解决。如何保证其他异步代码能够解决?
现在,它解决了这个问题。在测试运行期间,不再有任何控制台消息。测试仍然通过(不是很好)。但这似乎就像我只是落在比赛条件的另一端,而不是首先避免比赛条件。
我将从为什么需要此解决方案的原因开始。
原因是您对异步任务没有引用,并且需要测试断言才能运行之后异步任务。如果拥有它,则只需在其上单击await
,这将确保您的测试断言将在异步任务中运行。 (您的情况是ReactDOM.unmountComponentAtNode
)在您的示例中,异步任务位于componentDidMount
中,它可以响应调用,因此您没有对异步任务的引用。
通常,flushPromises
的简单实现是:
const flushPromises = () => new Promise(resolve => setImmediate(resolve));
此实现基于以下事实:javascript中的异步操作基于(javascript有几种类型的异步任务队列)。具体来说,承诺会在微任务队列中排队。每次异步操作(例如http请求)完成异步任务的出队并执行。任务队列
setImmediate
是一种获取回调并将其存储在setImmediate
上的方法,并将在事件循环的下一次迭代中调用。在微任务队列(包含承诺)中,Immediates Queue
被选中。让我们分析代码,我们正在创建一个新的Promise,它在Immediates Queue
的end
Micro-task queue
,这意味着它将在所有已兑现的诺言之后解决。希望这会有所帮助。
[注意]],如果在异步任务中加入新的诺言,它将在最后进入队列,这意味着resolve
返回的诺言将不在其后运行。
很少有帖子/视频以获取更多信息:
flushPromises
以上是关于刷新承诺队列?的主要内容,如果未能解决你的问题,请参考以下文章