在JavaScript中重入意味着什么?

在JavaScript中重入意味着什么?,javascript,Javascript,我见过,也见过 但仍然困惑的是,重入似乎是关于并发、纯和递归的。我不确定生成器是否是可重入性的实现,如果是,它与纯/递归或其他语言之间的关系如何 希望你的回答,谢谢 在JS中的意思与在其他语言中的意思相同:当例程仍在运行时再次调用时,会重新输入例程。在安全的情况下,它被称为可重入(其中“安全”是一个非常宽泛的术语,通常意味着“一切仍按预期工作”)——或者更正式地说,当以这种方式调用函数时,它仍然是可重入的 在JS中有一些场景与此相关(函数通常运行到完成时不会被其他东西“中断”): 该函数是异步

我见过,也见过

但仍然困惑的是,重入似乎是关于并发、纯和递归的。我不确定生成器是否是可重入性的实现,如果是,它与纯/递归或其他语言之间的关系如何

希望你的回答,谢谢

在JS中的意思与在其他语言中的意思相同:当例程仍在运行时再次调用时,会重新输入例程。在安全的情况下,它被称为可重入(其中“安全”是一个非常宽泛的术语,通常意味着“一切仍按预期工作”)——或者更正式地说,当以这种方式调用函数时,它仍然是可重入的

在JS中有一些场景与此相关(函数通常运行到完成时不会被其他东西“中断”):

  • 该函数是异步的。两个调用的一部分可能会交错运行。如果这种交织以开发人员没有预料到的方式发生,则称为竞争条件
  • 该函数接受(并调用)回调。用户提供的回调可能会再次调用该函数
  • 该函数是一个生成器函数。它被多次调用,发电机交替消耗
仅使用调用局部状态(或完全纯)的函数始终是可重入的。当函数修改全局状态时,事情会变得一团糟,尤其是当它“仅在函数调用期间”确实破坏了数据结构的不变量时

下面是一个不可重入生成器函数的简单示例:

var k = 0;
function* countTo(n) {
    while (k < n)
        yield k++;
    k = 0;
}
for (const x of countTo(3))
    console.log(x);
for (const y of countTo(7))
    console.log(y);
function* countTo(n) {
    for (var k = 0; k < n; k++)
        yield k;
}
哎呀。与可重入生成器函数编写的功能相同:

var k = 0;
function* countTo(n) {
    while (k < n)
        yield k++;
    k = 0;
}
for (const x of countTo(3))
    console.log(x);
for (const y of countTo(7))
    console.log(y);
function* countTo(n) {
    for (var k = 0; k < n; k++)
        yield k;
}
函数*countTo(n){
对于(var k=0;k
纯函数总是可重入的,但仅此而已。与纯度没有特殊关系。重入函数是一个可以安全调用的函数,即使对它的调用尚未完成。正如@Bergi所说,非纯函数可能是可重入的。在具有共享内存并发性的语言中,函数可以在不进行(直接或间接)递归的情况下重新输入,但在JavaScript等事件循环并发语言中,您不会看到非递归函数重新输入。但是在JavaScript中很难静态地判断哪些函数可能被重新输入。@MikeSamuel“但是在JavaScript这样的事件循环并发语言中,您不会看到非递归函数被重新输入。”,那么,generator是一个可重入函数吗?我认为在本文中“安全”指的是函数的约定,不是系统或语言级别的不变量。类似于“当函数重新输入时,不会发生未重新输入时不会发生的契约冲突。”Re“仅使用本地状态”,值得一提的是,由特定函数实例关闭的状态在此上下文中不算作本地。@MikeSamuel我认为不破坏系统或语言级契约是每个函数契约的一部分?但是是的,我没有想到“合同”这个词,这是个好主意。@Bergi谢谢你的回复!我想问的是,如何看待“while”中的“while”一词。依我看,只有那些支持并发的语言可以做“while”的事情,但在你的回答中,你似乎同意“generator”也是一个可重入函数。因此,我想知道“while”是指“函数上下文”还是“完全并发,如多线程”?@smalltowne契约所包含的函数上下文(如“调用
countTo
生成从0到n的所有数字”-当函数仍在生成数字时,对该函数的另一次调用不应产生干扰)。第二个实现是可重入的,第一个不是。