繁体   English   中英

获取 API - 它是阻塞代码还是非阻塞代码?

[英]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 来做人们过去使用XMLHttpRequestcallbacks做的同样的事情。

所以,老派的XMLHttpRequest XHR 和 fetch API 都不会阻止你的 DOM。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM