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