Javascript 递归:返回与布尔退出

Javascript 递归:返回与布尔退出,javascript,recursion,promise,fetch,Javascript,Recursion,Promise,Fetch,我对JavaScript非常陌生,我一直在使用这个api,我基本上只是在测试这些递归调用是如何工作的:正如您所看到的,一旦我点击data.id==6,我就会尝试停止调用 使用“return”退出递归调用与使用布尔调用有什么区别? 我认为他们会产生同样的产出;然而,他们没有。布尔值生成预期结果,而“return”生成无限循环。我以为这是最后一个电话了。我的思维过程中的漏洞在哪里 另外,请注意,在调用api调用时是否应该始终使用wait?当我取消wait时,它产生了一个无限循环,即使使用布尔方法也是

我对JavaScript非常陌生,我一直在使用这个api,我基本上只是在测试这些递归调用是如何工作的:正如您所看到的,一旦我点击data.id==6,我就会尝试停止调用

使用“return”退出递归调用与使用布尔调用有什么区别? 我认为他们会产生同样的产出;然而,他们没有。布尔值生成预期结果,而“return”生成无限循环。我以为这是最后一个电话了。我的思维过程中的漏洞在哪里

另外,请注意,在调用api调用时是否应该始终使用wait?当我取消wait时,它产生了一个无限循环,即使使用布尔方法也是如此。为什么

谢谢你抽出时间

    let bool = true;
    async function foo(index) {

        let var2 = await fetch(`https://jsonplaceholder.typicode.com/todos/${index}`)
        .then(blob => blob.json())
        .then(data => {
            if(data.id == 6) {
                return;
            }
        })
        .catch(err => console.log(err));


        foo(++index);
}

你是在承诺中回来的。承诺将被返回,这意味着,在你的例子中,var2将是未定义的返回值。但是,您再次调用foo时没有任何约束,因此在第一种情况下将始终调用它。在您给出的第二个示例中,您为递归调用添加了一个约束,因此不再调用它。

您在一个承诺内返回。承诺将被返回,这意味着,在你的例子中,var2将是未定义的返回值。但是,您再次调用foo时没有任何约束,因此在第一种情况下将始终调用它。在您给出的第二个示例中,您为递归调用添加了一个约束,因此不再调用它。

首先,您应该了解有关代码的两个方面:

这不是发出多个异步请求的正确方法。 您将异步等待语法与承诺链接混合在一起。 在第一个代码示例中,在then块内使用返回停止递归会导致无限循环,因为then块内的返回仅从传递给then函数的回调函数返回。它不会从外部函数返回

在第二个代码示例中,当bool变量的值设置为false时,函数停止递归地调用自身

要正确发出多个请求,请使用Promise.all函数。下面是一个演示如何使用Promise.all函数发出多个请求的示例

调用api调用时是否应始终使用wait

在异步函数内部,是的,并且不能在异步函数外部使用wait关键字

当我取下wait时,它产生了一个无限循环,即使是在 布尔方法。为什么

在这种情况下,在再次调用函数之前,您没有等待请求的结果,这将导致无限递归

您可以按如下所示更改代码以获得预期结果

async function foo(index) {
  try {
    const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${index}`);
    const data = await response.json();

    if (data.id === 6) {
      return;
    }

    foo(++index);

  } catch (error) {
    console.log(error.message);
  }
}

首先,您应该了解代码的两个方面:

这不是发出多个异步请求的正确方法。 您将异步等待语法与承诺链接混合在一起。 在第一个代码示例中,在then块内使用返回停止递归会导致无限循环,因为then块内的返回仅从传递给then函数的回调函数返回。它不会从外部函数返回

在第二个代码示例中,当bool变量的值设置为false时,函数停止递归地调用自身

要正确发出多个请求,请使用Promise.all函数。下面是一个演示如何使用Promise.all函数发出多个请求的示例

调用api调用时是否应始终使用wait

在异步函数内部,是的,并且不能在异步函数外部使用wait关键字

当我取下wait时,它产生了一个无限循环,即使是在 布尔方法。为什么

在这种情况下,在再次调用函数之前,您没有等待请求的结果,这将导致无限递归

您可以按如下所示更改代码以获得预期结果

async function foo(index) {
  try {
    const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${index}`);
    const data = await response.json();

    if (data.id === 6) {
      return;
    }

    foo(++index);

  } catch (error) {
    console.log(error.message);
  }
}

这个函数的中间部分:

data => {
  if (data.id == 6) {
    return;
  }
}

是一个函数。它内部的返回仅从此函数返回。因此,如果data.id为6,则返回。如果没有,我们将到达这个函数的末尾-也返回。因此,这里的返回没有任何效果。

在您的函数中间的这个比特:

data => {
  if (data.id == 6) {
    return;
  }
}
是一个函数。它内部的返回仅从此函数返回。因此,如果data.id为6,则返回。如果没有,我们将到达这个函数的末尾-也返回。因此,这里的返回没有任何效果。

您混合了async/Wait和Promise,但实际上这是同一事物的两个版本

假设您希望从远程服务获取某些内容,在本例中,您的获取是https…-你真的在发送一个请求,然后在完成后想做其他事情。这通常是通过回调完成的:

//伪代码,而不是实际的JS oldFetch'https…',结果=>{ //此代码在提取完成时激发 someOtherAsyncRequest…,secondREesult=>{ //当第二个异步操作完成时触发 }; }; //这里的代码立即启动,我 t不等待回调 您很快就会遇到这样一个问题:回调嵌套在回调中,错误跟踪非常混乱。解决方案是Promise,而不是Promise在成功时调用的回调函数,或者在失败时调用的回调函数。这使您可以在下一个函数还返回承诺时将这些回调请求链接在一起

fetch`https…`//返回带有响应的承诺 .thenblob=>blob.json//在json解析完成后返回一个承诺 .thendata=>{//不返回任何内容,因此链停止 ifdata.id==6{ 布尔=假; } 控制台日志数据; } .catcherr=>console.logerr;//捕获异常 请注意,这些then/catch语句都不会停止代码的执行,它们实际上只是将回调封装在一个对象中,以便更好地管理它们

async/await只是使Promise易于使用的语法,您仍然可以在Promise下进行切换,但async/await更易于阅读

async表示此函数返回一个承诺,但它不必返回

等待说把所有的代码放在后面然后

将它们放在一起,代码的可读性就会大大提高:

//与前面的代码示例完全相同 试一试{ const blob=wait fetch`https…`; const data=wait blob.json; ifdata.id==6{ 布尔=假; } 控制台日志数据; } catcherr{//Catch异常-如果使用wait,则可以在常规的try-Catch中使用异步 console.logerr; } 让我们将其应用于函数。它只与wait一起工作的原因是,如果没有wait,则整个函数在调用then代码之前完成,但使用它,函数的其余部分则在另一个then中完成

您正在混合语法,所以让我们只使用async/await:

异步函数fooindex{//async表示此函数可以返回承诺 试一试{ const blob=等待获取`https://jsonplaceholder.typicode.com/todos/${index}`; const data=wait blob.json; ifdata.id==6 return;//wait表示将退出父函数 控制台日志数据; } 捕手{ console.logerr; } 等待foo++索引; } 使用“return”退出递归调用与使用布尔调用有什么区别

您只是从回调返回,您需要通过解析承诺来处理它,或者只是等待它

当我取消wait时,它产生了一个无限循环,即使使用布尔方法也是如此。为什么

你让布尔=真;是全局的,如果您不等待获取。。。下一行立即执行,调用foo。JS将在检查fetch的结果之前完成同步代码,因此在任何fetch结果更改bool=false之前,您将用完递归

调用api调用时是否应始终使用wait

如果API是异步的或基于web的,则是。作为一般规则,一旦某些代码是异步的,那么所有的代码都必须是异步的——您不能或不应该用同步代码调用异步方法。最佳实践是在任何地方使用async/await并为其进行设计。

您将async/await和Promise混合在一起,但实际上这是同一事物的两个版本

假设您希望从远程服务获取某些内容,在本例中,您的获取是https…-你真的在发送一个请求,然后在完成后想做其他事情。这通常是通过回调完成的:

//伪代码,而不是实际的JS oldFetch'https…',结果=>{ //此代码在提取完成时激发 someOtherAsyncRequest…,secondREesult=>{ //当第二个异步操作完成时触发 }; }; //这里的代码立即启动,它不等待回调 您很快就会遇到这样一个问题:回调嵌套在回调中,错误跟踪非常混乱。解决方案是Promise,而不是Promise在成功时调用的回调函数,或者在失败时调用的回调函数。这使您可以在下一个函数还返回承诺时将这些回调请求链接在一起

fetch`https…`//返回带有响应的承诺 .thenblob=>blob.json//在json解析完成后返回一个承诺 .thendata=>{//不返回任何内容,因此链停止 ifdata.id==6{ 布尔=假; } 控制台日志数据; } .catcherr=>console.logerr;//捕获异常 请注意,这些then/catch语句都不会停止代码的执行,它们实际上只是将回调封装在一个对象中,以便更好地管理它们

async/await只是使Promise易于使用的语法,您仍然可以在Promise下进行切换,但async/await更易于阅读

async表示此函数返回一个承诺,但它不必返回

等待说把所有的co 在这之后,在

将它们放在一起,代码的可读性就会大大提高:

//与前面的代码示例完全相同 试一试{ const blob=wait fetch`https…`; const data=wait blob.json; ifdata.id==6{ 布尔=假; } 控制台日志数据; } catcherr{//Catch异常-如果使用wait,则可以在常规的try-Catch中使用异步 console.logerr; } 让我们将其应用于函数。它只与wait一起工作的原因是,如果没有wait,则整个函数在调用then代码之前完成,但使用它,函数的其余部分则在另一个then中完成

您正在混合语法,所以让我们只使用async/await:

异步函数fooindex{//async表示此函数可以返回承诺 试一试{ const blob=等待获取`https://jsonplaceholder.typicode.com/todos/${index}`; const data=wait blob.json; ifdata.id==6 return;//wait表示将退出父函数 控制台日志数据; } 捕手{ console.logerr; } 等待foo++索引; } 使用“return”退出递归调用与使用布尔调用有什么区别

您只是从回调返回,您需要通过解析承诺来处理它,或者只是等待它

当我取消wait时,它产生了一个无限循环,即使使用布尔方法也是如此。为什么

你让布尔=真;是全局的,如果您不等待获取。。。下一行立即执行,调用foo。JS将在检查fetch的结果之前完成同步代码,因此在任何fetch结果更改bool=false之前,您将用完递归

调用api调用时是否应始终使用wait


如果API是异步的或基于web的,则是。作为一般规则,一旦某些代码是异步的,那么所有的代码都必须是异步的——您不能或不应该用同步代码调用异步方法。最佳实践是在任何地方使用async/await并为其进行设计。

根据我的经验,return是一种更具可读性的打破递归的方法,因为您使用的是async await,它可以简化并像sync Code一样读取。根据我的经验,return是一种更具可读性的打破递归的方法,因为您使用的是async await,它可以简化,读起来像同步代码一样谢谢。我没有意识到我只是回电话回来。我感谢你详细的答复。我没有意识到我只是回电话回来。非常感谢您的详细回复非常感谢您的详细回复。这很有帮助!非常感谢您的详细回复。这很有帮助!