Fetch APIs - 它是阻塞代码还是非阻塞代码?

Pra*_*rya 5 javascript dom promise ecmascript-6 fetch-api

我已经看了Fetch API几天了。

在学习的过程中,我遇到了“使用fetch()不会阻止你的 DOM”这一说法,因为它使用了 Promise。

很高兴继续学习这些教程并查看一些新教程,我​​看到一个人在演示文稿中说“使用fetch()确实会阻塞你的 DOM”

谁能告诉我它是两者中的哪一个?

nem*_*035 11

fetch在阻塞/非阻塞代码的意义上使用归结为同步和异步代码之间的区别。

JavaScript 的一种设计范式称为Run to Completion,归结为这样一个事实:当前正在执行的一段 JS 代码不能被另一段代码中断。换句话说,一个函数以同步方式运行直到它完成(另见最后的警告)。

当您有异步代码时,例如包装在承诺中的代码(fetch正在使用的代码),它会被安排在稍后运行,在所有同步代码完成运行之后,以及在所有其他先前计划的任务之后(microtasks的承诺)。

这提供了一个时间间隙,允许运行 JS 的系统的其他部分,例如浏览器中的 DOM,在知道 JS 不会进入的情况下,自由地操作它们与 JavaScript 引擎共享的系统部分他们的路。

因此,从最广泛的意义上讲,fetch是非阻塞的,不会阻塞 DOM。

应该注意的是,promise 表示通过异步调度链(promise 链)连接的同步代码块,因此从技术上讲,其中的某些部分fetch确实会阻塞 DOM,但对于大多数目的,整个过程可以被认为是非阻塞的。有关示例,请参阅mpen 的答案


注意:在 ES6 中引入生成器后,函数不再是 JavaScript 中的原子执行单元。使用yield和之后await,JS 函数能够分解为多个同步执行代码的异步块。


Dav*_*son 5

如果阻塞意味着其他脚本和请求在其请求完成之前无法运行:no

如果您的意思是阻止页面加载完成:yes,它似乎会阻止。

这里有一些我做了一些测试来比较演示,要求在谷歌上搜索:什么是狗?

fetch()似乎确实阻止了window.onload完成 https://jsfiddle.net/84uopaqb/7/

XMLHttpRequest,这不会阻止window.onload完成 https://jsfiddle.net/84uopaqb/5/

$.get()这也不会阻止window.onload完成 https://jsfiddle.net/84uopaqb/1/

如果必须使用 fetch,将fetch请求包装在 a 中setTimeout是解决此问题的方法。

警告:我只在 FF Quantum 中对此进行了测试,而且也不是很彻底......但是话虽如此,您应该支持所有主要浏览器。即使它在其他浏览器中是非阻塞的,它仍然不是一个可行的解决方案。