【问题标题】:Using ES6 Generators with XMLHttpRequest使用带有 XMLHttpRequest 的 ES6 生成器
【发布时间】:2016-09-10 00:45:28
【问题描述】:

我正在尝试简化使用 ES6 生成器进行 AJAX 调用的方式。但是,我遇到了一些问题:

let xhr = new XMLHttpRequest()

function *statechange() {
    yield xhr.readyState;
}

let gen = statechange();

xhr.open("GET", myUrl, true);
xhr.onreadystatechange = function() {console.log(gen.next())};
xhr.send();

只是对我正在尝试做的事情的简要说明:我想产生每个请求状态更改的就绪状态。我在生成器的每次迭代中记录readyState 字符串。但是当我运行这段代码时,我得到:

{value: 2, done: false}
{value: undefined, done: true}
{value: undefined, done: true}

表面上看起来不错,但如果我做一个老式的 XHR:

//... new XMLHttpRequest()...
xhr.onreadystatechange = function() {console.log(xhr.readyState)}

我明白了:

2
3
4

那么...我在使用生成器时哪里出了问题?


更新:

更奇怪的是,如果我在生成器中记录readyState

//                                                     HERE
xhr.onreadystatechange = function() {console.log(xhr.readyState, gen.next())};

我明白了:

2, {value: 2, done: false}
3, {value: undefined, done: true}
4, {value: undefined, done: true}

这意味着,当调用next() 方法时,正确的readyState 可用。我只能猜测我使用的yield语句只注册了一次,所以生成器只分配了一个槽。我想既然onreadystatechange 被多次调用,就会分配更多的插槽。我该如何解决这个问题?

【问题讨论】:

  • gen 到达函数的末尾,因此 完成 (另外,这并没有真正简化 XHR,而是监听负载/错误,您可以编写它们作为承诺)

标签: javascript ajax ecmascript-6 generator


【解决方案1】:

当你“调用”一个生成器函数时,它会一直运行到第一个 yield 语句,然后暂停直到它的 next 方法被调用。在此之后,它会继续运行,直到出现另一个 yield 语句或函数或控件离开函数。在后一种情况下,对next 方法的所有调用都将返回undefined

你想要的是一个循环,在每次迭代时检查 xhr 的readyState

function *statechange() {
  while(true) { // loop forever
    yield xhr.readyState;
  }
}

如果您熟悉 Python 中的生成器,则完全一样。

我将赞同@Paul S. 的评论,即这并不能真正简化 xhrs,您应该查看 promises。

【讨论】:

    猜你喜欢
    • 2018-12-03
    • 2016-06-24
    • 2018-04-14
    • 1970-01-01
    • 2017-01-10
    • 2023-03-25
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    相关资源
    最近更新 更多