[英]Fetch APIs - Is it blocking or non-blocking code?
几天来我一直在研究Fetch API
。
在学习的过程中,我遇到了“使用fetch()
不会阻止你的 DOM”这句话,因为它使用了 promises。
愉快地继续学习这些教程并查看一些新教程,我看到一个人在演示文稿中说“使用fetch()
确实会阻止您的 DOM” 。
谁能教我这是两个中的哪一个?
在阻塞/非阻塞代码的意义上使用fetch
归结为同步代码和异步代码之间的区别。
JavaScript 的一种设计范式称为Run to Completion ,它归结为这样一个事实,即当前正在执行的一段 JS 代码不能被另一段代码打断。 换句话说,一个函数以同步方式运行直到它完成(另请参阅最后的警告)。
当你有异步代码时,比如包裹在承诺中的代码( fetch
正在使用的代码),它会被安排在稍后运行,在所有同步代码完成运行之后,以及在所有其他先前计划的任务之后( 承诺的微任务)。
这提供了一个时间间隙,允许运行 JS 的系统的其他部分,例如浏览器中的 DOM,可以自由地操作它们与 JavaScript 引擎共享的系统部分,知道 JS 不会进入他们的路。
因此,从广义上讲, fetch
是非阻塞的,不会阻塞 DOM。
应该注意的是,promises 表示通过异步调度链( promise 链)连接的同步代码块,因此从技术上讲, fetch
的某些部分确实会阻塞 DOM,但对于大多数目的而言,整个过程可以被认为是非阻塞的。 有关示例,请参见mpen 的答案。
注意:在 ES6 中引入生成器后,函数不再是 JavaScript 中的原子执行单元。 通过yield
和之后的await
,JS 函数能够分解为多个同步执行代码的异步块。
我认为这个人想说的是fetch
本身正在阻塞。 如同,创建 HTTP 请求并发送它所花费的时间是阻塞的,但是当请求发出时您的脚本和 UI不会被阻塞。 您的then()
回调也将被阻塞。
也就是说,发送您的请求只需要五分之一毫秒,您无需担心。
> t=performance.now(),fetch('.'),(performance.now()-t)
0.139999999984866
如果您的意思是阻止,则其他脚本和请求在其请求完成之前无法运行:否。
如果您的意思是阻止页面加载完成:是的,它似乎会阻止。
这里有一些我做的一些测试来比较演示,请求搜索到谷歌:什么是狗?
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
请求包装在setTimeout
中是解决此问题的一种方法。
警告:我只在 FF Quantum 中测试过这个,也不是很彻底……但话虽这么说,你应该支持所有主要浏览器。 即使它在其他浏览器中是非阻塞的,它仍然不是一个可行的解决方案。
您可以像这样使用 fetch API:
fetch(url)
.then(function(data) {
// do something with the data fetched
})
.catch(function(error) {
// error handling
});
是的, 这不会阻止您的 DOM 。 是的, 你的代码是异步的。
然而,这同样适用于使用XMLHttpRequest
的旧式 XHR 请求:
var getJSON = function(url, successHandler, errorHandler) {
// 1. Make an Ajax call to your json file
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.onreadystatechange = function() {
var status, data;
if (xhr.readyState == 4) {
status = xhr.status;
if (status == 200) {
// 2. Parse the json file once it's been received
data = JSON.parse(xhr.responseText);
successHandler && successHandler(data);
} else {
errorHandler && errorHandler(status);
}
}
};
xhr.send();
};
getJSON('data.json', function(data) {
// 3. Do something with the content of the file once it's parsed
}, function(status) {
// Error handling goes here
});
fetch API 只是为您提供了一个更现代的基于promise的 API 来做人们过去使用XMLHttpRequest
和callbacks做的同样的事情。
所以,老派的XMLHttpRequest
XHR 和 fetch API 都不会阻止你的 DOM。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.