什么时候抛出(错误)和返回(值)在javascript迭代器中有用?
在javascript中,迭代器可以有什么时候抛出(错误)和返回(值)在javascript迭代器中有用?,javascript,iterator,redux-saga,Javascript,Iterator,Redux Saga,在javascript中,迭代器可以有throw(error)和return(value)方法return(value)使迭代器有机会查看value,并应返回{value:value,done:true}抛出(错误)使迭代器有机会看到并可能捕获错误。如果捕获到错误,throw应返回下一个值。如果未捕获异常,则它应等同于返回(未定义)。下面是这些机制的一个例子: 函数*test(){ 试一试{ 产量1; }捕获(e){} 消费者成本=收益率2; 来自消费者的收益; //我不知道如何访问传递给生成器
throw(error)
和return(value)
方法return(value)
使迭代器有机会查看value
,并应返回{value:value,done:true}
<代码>抛出(错误)使迭代器有机会看到并可能捕获错误。如果捕获到错误,throw
应返回下一个值。如果未捕获异常,则它应等同于返回(未定义)
。下面是这些机制的一个例子:
函数*test(){
试一试{
产量1;
}捕获(e){}
消费者成本=收益率2;
来自消费者的收益;
//我不知道如何访问传递给生成器返回的值
}
const iter=test()[Symbol.iterator]();
log(iter.next());
log(iter.throw(新错误('catch me'));
console.log(iter.next(9));
log(iter.next());
控制台日志(iter.return(0));
(和a一样)
我的问题是:为什么?有人对迭代器的这种控制API反转有一个合理的用例吗?在什么条件下,迭代器处理在使用它时发生的错误是有意义的?如果确定要结束迭代器并且不能进一步影响迭代器API的行为,您希望何时传递一个返回值
我要说的是,我所知道的一个用例是redux saga,他们利用了迭代器的控制API反转,似乎是穷人的异步/等待。如果有人熟悉该工具的设计或使用,他们的选择还有其他好处吗?首先,并不是所有迭代器都有返回和抛出功能。迭代器唯一需要的是
next
。但生成器函数创建的迭代器确实有返回
和抛出
我要说的是,我所知道的一个用例是redux saga,他们利用了迭代器的控制API反转,似乎是穷人的异步/等待
我认为这是倒退。生成器不是async/await的糟糕版本;async/await是生成器的狭义用法。事实上,async/await的旧等价物实际上是使用生成器实现的,如在库中找到的那样。既然异步/等待是核心语言的一部分,我不知道底层C++代码是否真的使用了生成器,但从历史上和概念上来说,它是与解决承诺的狭义案例相联系的生成器的产物。
使用像redux saga这样的库,不仅可以获得类似await的语法,还可以支持更复杂的事情,例如任务取消,这是async/await无法做到的。任务取消取决于返回
的工作方法。还支持错误处理,这可以通过throw
方法实现
因此,生成器是一个非常广泛的工具,除其他外,它可以用来建模异步行为。因为它们的范围很广,所以它们附带了一组函数,这些函数不仅能够对迭代进行建模。我认为生成器不仅仅是一种迭代方式,而是在两段代码之间进行双向对话。在你可能想要传达的事情中,有一件事是“有问题”或“我们到此为止”,这就是掷球和回击的目的
如果确定要结束迭代器并且不能进一步影响迭代器API的行为,您希望何时传递一个返回值
实际上,它仍然可以影响它。如果生成器使用try/finally,.return()
会将生成器发送到finally块,在那里它可以运行任意数量的代码。生成器甚至可以在这个finally块中屈服,其行为与finally块之前相同。继续以redux saga为例,生成器的这个特性用于在取消时支持回滚
function* exampleSaga() {
try {
// start working on something, with at least one yield
} finally {
if (yield cancelled()) {
// roll back
}
}
}
以下是我到目前为止的想法: 与使用async/await与远程代码交互相比,将代码编写为协同程序操纵的生成器具有以下优势:
产生
、抛出
、和返回
,而不仅仅是解决
和拒绝
<代码>返回在这种情况下,表示普通承诺中不可用的on选项,即取消最后,关于生成器何时适合捕获消费者的错误,答案是:当消费者是一个协同程序,在执行生成器指示的操作时遇到错误,在这种情况下,生成器,作为导致错误的操作的来源,也应该了解如何处理它。我没有时间对此给出正确的答案,并且怀疑有人会说这个问题过于开放或基于观点(什么是“可辩护的”用例?)。虽然迭代器允许有
返回
和抛出
,但它们真正有用的地方是生成器。使用生成器,您可以构建协同程序。协同程序不仅仅是“穷人的异步
/等待
”“通常,这些方法的调用方应该在调用它们之前检查它们是否存在。某些ECMAScript语言功能,包括of、yield*
和数组解构,在执行存在性检查后调用这些方法。大多数接受Ite的ECMAScript库函数