【问题标题】:Why is the Axios .then and .catch function incrementing my index?为什么 Axios .then 和 .catch 函数会增加我的索引?
【发布时间】:2018-12-25 13:50:14
【问题描述】:

我有一个循环,它最多对 API 端点进行五次调用以验证 ids。在完成循环之前的第一次迭代中,我的增量变量从0 变为1

我指出,在控制台在请求之前记录变量之后,然后在每个回调中,无论请求是好是坏,都会发生这种情况。只要在.then 回调或.catch 回调中调用变量,索引就会增加,我不知道为什么。我测试了不同的变量名,仍然得到相同的结果。有人对此有想法吗?

我还在 React 中使用了 .fetch() 方法,同样的事情也发生在 .then 函数中,所以我认为这不是 axios 特有的。

这是我的功能:

isValidAIN(ains) {
  var control = this;
  var length = ains.length;

  if (ains.length > 0) {
    for (var i = 0; i < length; i++) {
      if (ains[i].length !== 10) {
        if (ains[i].length === 0) {
          this.state.errors["ain[" + i + "]"] = "";
          this.state.validAINS[i] = true;
        } else {
          this.state.errors["ain[" + i + "]"] = "This AIN Number Must Contain 10 Digits";
          this.state.validAINS[i] = false;
        }        
        this.setState(this.state);        

      } else {
        // v this logs 0
        console.log("i: ", i);

        axios
          .get("/myendpoint/?ain=" + ains[i])
          .then((res) => {
            //  v this logs 1
            console.log("in then: ", i);
            console.log("res: ", res);
            control.state.errors["ain[" + i + "]"] = "";
            control.state.validAINS[i] = true;
            control.setState(control.state);
          })
          .catch((err) => {
            //  v this logs 1
            console.log("i in catch", i);

            if (err.response.status == 404) {
              control.state.errors["ain[" + i + "]"] = "AIN Is Invalid";
              console.log(control.state.errors["ain[" + i + "]"]);
              control.state.validAINS[i] = false;
              control.setState(control.state);
              return false;
            }
          });

        // fetch("/myendpoint/?ain=" + ains[i])
        // .then(res => res.json())
        // .then(
        //     (result) => {
        //         console.log("success: ", result);
        //         if(result == null) {
        //             control.state.errors["ain[" + i + "]"] = "AIN Is Invalid";
        //             control.state.validAINS[i] = false;
        //             control.setState(control.state);
        //             return false;
        //         }
        //         else {
        //             control.state.errors["ain[" + i + "]"] = "";
        //             control.state.validAINS[i] = true;
        //             control.setState(control.state);
        //         }
        //     },
        //     (error) => {
        //         console.log("error: ", error);
        //     }
        // )
        // .catch( 
        //     (err) => {
        //         console.log("Error from catch: ", err);
        //     }
        // )
      }
    }
  } else {
    return false;
  }
}

【问题讨论】:

  • 不要不要直接修改状态,除非你在构造函数中。
  • axios请求是异步的,var声明的变量的作用域是封闭函数。当 axios 请求完成时,这个变量将是循环的最大值,因为循环已经完成。将 var 更改为 let 以使 i 改为使用块范围。
  • 啊哈@Tholle 非常感谢你成功了。
  • 感谢 JakeG 和 Tholle 的快速修订

标签: javascript reactjs loops fetch axios


【解决方案1】:

axios请求是异步的,var声明的变量作用域是封闭函数。当 axios 请求完成时,这个变量将是循环的最大值,因为循环是同步且完整的。

varlet 更改为 i 以改为使用块作用域。

for(let i = 0; i < length; i++) { ... }

【讨论】:

  • 这解决了问题,但现在创建了 onBlur 问题并提交不重新检查功能。 i 的值是否存储在此函数的范围内?循环好像不能再调用了;
  • @JakeG 这令人沮丧。我不太确定我明白你的意思。如果找不到问题,请考虑使用Minimal, Complete, and Verifiable example 创建另一个问题。
【解决方案2】:

因为 axios 调用是异步的。

您正在执行一个 for loop,它只是循环通过 ains.length,这会在几毫秒内发生。您将 i 定义为一个 var,在 for 循环中的每个循环之后递增。

因此,如果您在 then / catch 中,则变量 i 已经处于最大值(在您的情况下为 1)。

i 是变量而不是常量。使用 i 时,您正在引用内存中的该指针。如果您希望i 在每个循环中都是唯一的,您应该将其定义为let 而不是var。这将为循环的每次调用创建一个唯一值 i

【讨论】:

  • 这解决了问题,但现在创建了 onBlur 问题并提交不重新检查功能。 i 的值是否存储在此函数的范围内?循环好像不能再调用了;
猜你喜欢
  • 1970-01-01
  • 2010-11-04
  • 2017-02-25
  • 1970-01-01
  • 2018-06-05
  • 2023-01-22
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
相关资源
最近更新 更多