【问题标题】:Should I call XMLHttpRequest async within promise? [duplicate]我应该在承诺中调用 XMLHttpRequest 异步吗? [复制]
【发布时间】:2019-06-04 14:09:40
【问题描述】:

我在promise 中使用基本的XMLHttpRequest。由于promise 的异步特性,我一直认为XMLHttpRequest 同步很好,但由于我的浏览器会警告我,所以我想确认一下。

mwe 将是:

call(arg) {
    return new Promise(resolve => {
        let xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://localhost:8080?' + arg.name, false);
        xhr.send();
        resolve({body: {result: xhr.responseText}});
    });
}

【问题讨论】:

  • 不,这不好。在某些特定工具之外,JavaScript 是单线程的,如果您使用同步 XHR,您将导致 UI 在 Promise 中像往常一样挂起,就像您在事件侦听器中一样,setTimeout 回调,...。
  • 旁注:如果你想要启用承诺的 ajax,只需使用fetch

标签: javascript promise xmlhttprequest


【解决方案1】:

我应该在 promise 中调用 XMLHttpRequest async 吗?

是的,异步(非同步)。

由于 Promise 的异步特性,我一直认为拥有 XMLHttpRequest 同步就可以了...

并非如此,原因如下:

  1. 异步另一个线程上的不同。您仍在阻塞主 UI 线程。

  2. 承诺执行器函数(您传递给new Promise 的函数)无论如何都会同步执行。因此,您的 call 在 ajax 调用完成之前不会返回,因为它是同步调用。

承诺不会改变正在完成的工作的性质。它们只是提供一致的标准化语法来观察正在完成的工作的结果(通常是异步工作,但并非必须如此)。

promise 唯一实现异步的是调用thencatchfinally 处理程序。有关详细信息,请参阅此 sn-p 中的 cmets 和结果:

// The promise executor is called *synchronously*.
// This outputs 1, 2, 3, not 1, 3, 2:
console.log(1);
new Promise(resolve => {
  console.log(2);
  resolve();
});
console.log(3);

// `then`, `catch`, and `inally` handlers are called asynchronously, even if
// the promise is already settled (because it would be chaotic to call them
// synchronously *sometimes* [because the promise is already settled when you
// call `then`/`catch/`finally`] but not *other* times [because it isn't
// settled yet when you call `then`/`catch/`finally`]).
// This outputs A, B, C, not A, C, B
console.log("A");
Promise.resolve().then(() => console.log("C"));
console.log("B");

不要做同步 ajax,在 2019 年没有充分的理由。


附注:如果您想要启用 Promise 的 ajax,请使用 fetch

【讨论】:

  • 好的,有道理,那我就这么做。我会尝试找出fetch 部分。因为我必须返回一个承诺,所以我可以提供一个 API。
  • @magu_ - fetch 返回一个承诺。尽管原始的fetch API 具有a surprising "feature" (这是我贫血的小博客上有关它的帖子的链接),但您可能想要包装它。XMLHttpRequest 也不会很快消失,因此您可以将您的 false 更改为 true 而暂时不用担心 fetch。编码愉快!
  • 这就是我最终要做的,因为我需要对响应的格式进行一些调整。感谢您的快速帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多