【问题标题】:Why not a sync version of async APIs like in XHR?为什么不像 XHR 中的异步 API 的同步版本?
【发布时间】:2020-05-26 22:53:05
【问题描述】:

我的想法是所有WebAPIs 都是async,因为事情是在JavaScript 运行时之外处理的。但我知道我可以同步发送XMLHttpRequest 请求。所以我对此有几个问题。

XMLHttpRequest API 是 Javascript 运行时的一部分吗? 如果是这样,如何异步发送请求? 为什么不自己实现其他有用的 Javascript API 而不将它们暴露为 WebAPIs?

XMLHttpRequest API 是 WebAPIs 的一部分吗? 那么,为什么没有其他同步 API 呢?为什么不用setTimeout 同步API?

【问题讨论】:

  • XMLHttpRequest浏览器 的一部分,而不是 JavaScript。进行同步调用的能力伴随着冻结用户界面直到请求完成的惩罚。这基本上是一个直到最近才修复的设计错误。
  • 因为事情是在 JavaScript 运行时之外处理的。” - 不,这不是事情异步的原因。也有许多同步 Web api,例如整个 DOM 操作。

标签: javascript asynchronous xmlhttprequest


【解决方案1】:

XMLHttpRequest API 是 Javascript 运行时的一部分吗?

这取决于您所说的“JavaScript 运行时”是什么意思。它们不是 JavaScript 标准库的一部分,不。它们是网络浏览器中主机提供的功能。

XMLHttpRequest API 是 WebAPI 的一部分吗?

是的,它是一个网络 API。

那么,为什么没有其他同步 API?

有。例如,几乎所有的 DOM 操作都是同步的。但是,需要大量时间(如网络请求)并从主 ​​UI 线程(默认情况下 JavaScript 在浏览器中运行的地方)启动的事情最好异步完成,以避免阻塞该线程并阻止 UI 更新。所以XMLHttpRequest 默认是异步的(并且使用标志使其同步已被弃用),fetch 始终是异步的,而其他各种可能需要时间的操作都是异步的。

在现代环境中,¹ 使用异步 API 与使用同步 API 一样简单,这要归功于 async 函数:

async function showMoreData() {
    const response = await fetch("/more/data/please");
    if (!response.ok) {
        throw new Error("HTTP error " + response.status);
    }
    const data = await response.json();
    for (const entry of data) {
         // ...do something...
    }
}

¹“现代环境” - 现在大多数浏览器都原生支持 async 函数,如果您必须针对 IE11 或其他过时的浏览器(遗憾的是我们中的许多人都这样做!),您可以使用像 Babel 这样的工具来转换您的现代将代码转换为将在这些环境中运行的旧代码。你写最新的东西,他们把它变成 IE11 可以理解的东西。

【讨论】:

  • 出于某种原因,我认为诸如 DOM 操作 API 之类的东西是 Javascript 的一部分(我猜它是 JavaScript 的标准库 API 正确的说法),我认为这就是它们是同步的原因。显然不是。
  • @s1n7ax - 这是完全可以理解的,人们学习 JavaScript 的第一个(通常也是唯一一个)地方往往是在浏览器中,所以事情有点混为一谈。 :-) JavaScript 的标准库非常小(甚至 setTimeoutsetInterval 都是主机提供的)。 JavaScript 是一种通用语言,不限于浏览器或特定于浏览器,因此 DOM 不是它的一部分。如果您想知道某些东西是主机提供的还是内置的,您可以通过检查the spec 来判断——如果它不存在,它就是主机提供的。 :-D
猜你喜欢
  • 1970-01-01
  • 2016-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-09
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多