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

时间:2017-07-29 18:52:35

标签: javascript dom ecmascript-6 promise fetch-api

我现在已经看了Fetch API几天了。

在学习的过程中,我发现了声明"使用fetch()并不会阻止你的DOM" ,因为它使用了promises。

很高兴推进这些教程并查看一些新教程,我​​看到一个人说明&#34;使用fetch()会在演示文稿中阻止你的DOM&#34; 。< / p>

任何人都可以教育我这两者中的哪一个?

4 个答案:

答案 0 :(得分:4)

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

JavaScript的设计范例之一被称为Run to Completion,它实质上意味着当前正在执行的一段JS代码不会被另一段代码中断。换句话说,函数以同步方式运行。

当您拥有异步代码时,例如promises(fetch所基于的代码),它会被安排在所有同步代码完成运行之后以及之前所有其他代码之后运行任务(承诺的microtasks)。

这提供了一个时间间隔,允许运行JS的系统的其他部分(例如浏览器中的DOM)自由地操作他们与JavaScript引擎共享的系统部分,因为知道JS赢了妨碍他们。

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

应该注意的是,promises表示通过异步调度链(the promise chain)连接的同步代码块(函数),所以从技术上讲,fetch的某些部分会阻止DOM,但整个过程可以在大多数情况下被视为非阻塞。有关示例,请参阅the answer by mpen

答案 1 :(得分:2)

我认为那个人试图说的是fetch本身就是封锁的。与此同时,创建HTTP请求并发送它的时间是阻止的,但是在请求结束时,您的脚本和UI 不会被阻止。您的then()回调也会被阻止。

也就是说,发送您的请求只需要五分之一毫秒,您无需担心。

> t=performance.now(),fetch('.'),(performance.now()-t)
0.139999999984866

答案 2 :(得分:1)

如果阻止您的意思,其他脚本和请求在请求完成之前无法运行:

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

以下是一些测试我做了一些比较演示,请求搜索google:什么是狗?

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中包装setTimeout请求是此问题的解决方法。

<强>买者: 我只在FF Quantum中对此进行了测试,而且不是很彻底......但话虽如此,你应该支持所有主流浏览器。即使它在其他浏览器中没有阻塞,它仍然不是一个可行的解决方案。

答案 3 :(得分:0)

您可以像这样使用fetch API:

fetch(url)
.then(function(data) {
    // do something with the data fetched
})
.catch(function(error) {
    // error handling
});

是的,this doesn't block your DOM。是的,your code is asynchronous

但是,同样适用于使用XMLHttpRequest的oldschool 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做同样的事情。

因此,oldschool XMLHttpRequest XHR和fetch API都不会阻止你的DOM。