【问题标题】:why this call back gives infinity loop为什么这个回调会产生无限循环
【发布时间】:2021-12-19 13:11:32
【问题描述】:

所以我正在学习 javascript 中的 async-await 以及当我尝试执行此回调地狱时(我知道这不是最佳实践,但我必须学习它) 我第二次调用它一直调用自己的函数(无限循环) 您可以运行代码以了解更多信息,因为在我看来没有任何问题我花了过去 2 天试图理解问题,但我最终到了这里

代码:

const xhr = new XMLHttpRequest();
const url = new URL("https://www.breakingbadapi.com/api/quotes");

const moveiData = (link, callBack) => {
  xhr.addEventListener("readystatechange", () => {
    if (xhr.readyState === 4 && xhr.status == 200) {
    } else if (xhr.readyState === 4) {
      callBack("could not fetch data");
    }
  });

  xhr.open("GET", link);

  xhr.send();
};

moveiData(url, (response) => {
  console.log(response);

  moveiData(url, (response) => {
    console.log(response);
  });
});

【问题讨论】:

  • 您是否在 if 语句中调用了callback()(成功案例)?
  • 不仅如此,每次调用 moveiData 只会添加另一个监听器。
  • 据我所知,您调用了 2 次 moveiData。但是 xhr.addEventListener 正在监听同一个事件两次。你应该在函数之外定义它

标签: javascript api async-await promise asynccallback


【解决方案1】:
const url = new URL("https://www.breakingbadapi.com/api/quotes");

const moveiData = (link, callBack) => {
    const xhr = new XMLHttpRequest();
    xhr.addEventListener("readystatechange", () => {
    if (xhr.readyState === 4 && xhr.status == 200) {
    } else if (xhr.readyState === 4) {
      callBack("could not fetch data");
    }
  });

  xhr.open("GET", link);
  xhr.send();
};

moveiData(url, (response) => {
  console.log(response);
});

【讨论】:

    【解决方案2】:

    不要重复使用相同的 XMLHttpRequest 对象。每次调用该函数时声明一个新函数,并确保在有肯定响应时在回调中返回一些数据。

    const url = new URL('https://www.breakingbadapi.com/api/quotes');
    
    const moveiData = (link, callBack) => {
    
      const xhr = new XMLHttpRequest();
    
      xhr.addEventListener('readystatechange', () => {
        if (xhr.readyState === 4 && xhr.status == 200) {
          callBack(JSON.parse(xhr.response));
        } else if (xhr.readyState === 4) {
          callBack('could not fetch data');
        }
      });
    
      xhr.open("GET", link);
      xhr.send();
    
    };
    
    moveiData(url, function (response) {
      console.log(response);
      moveiData(url, function (response) {
        console.log(response);
      });
    });

    您可能会发现相对较新的fetch APIthe async/await process 有点more rewarding

    const url = 'https://www.breakingbadapi.com/api/quotes';
    
    function getData(url) {
      return fetch(url);
    }
    
    async function main() {
      try {
        const res = await getData(url);
        console.log(await res.json());  
      } catch (err) {
        console.log(err);
      }
    }
    
    main();
    

    【讨论】:

      【解决方案3】:

      在那个问题上你有三个选择。

      1- 您添加了一个新的事件侦听器,您应该在响应时将其移除。

      const xhr = new XMLHttpRequest();
      const url = new URL("https://www.breakingbadapi.com/api/quotes");
      
      const moveiData = (link, callBack) => {
        const handler = () => {
          if (xhr.readyState === 4 && xhr.status == 200) {
            xhr.removeEventListener("readystatechange", handler);     
            callBack(JSON.parse(xhr.response));
          } else if (xhr.readyState === 4) {
            callBack("could not fetch data");
          }
        };
      
        const a = xhr.addEventListener("readystatechange", handler);
      
        xhr.open("GET", link);
      
        xhr.send();
      };
      
      moveiData(url, (response) => {
        console.log(response);
      
        moveiData(url, (response) => {
          console.log(response);
        });
      });
      

      2- 使用 onreadystatechange 回调。

      const xhr = new XMLHttpRequest();
      const url = new URL("https://www.breakingbadapi.com/api/quotes");
      
      const moveiData = (link, callBack) => {
        xhr.onreadystatechange = () => {
          if (xhr.readyState === 4 && xhr.status == 200) {   
            callBack(JSON.parse(xhr.response));
          } else if (xhr.readyState === 4) {
            callBack("could not fetch data");
          }
        };
      
        xhr.open("GET", link);
      
        xhr.send();
      };
      
      moveiData(url, (response) => {
        console.log(response);
      
        moveiData(url, (response) => {
          console.log(response);
      
        });
      });
      

      3- 为每个函数声明新的 XMLHttpRequest。

      const url = new URL('https://www.breakingbadapi.com/api/quotes');
      const moveiData = (link, callBack) => {
        const xhr = new XMLHttpRequest();
      
        xhr.addEventListener('readystatechange', () => {
          if (xhr.readyState === 4 && xhr.status == 200) {
            callBack(JSON.parse(xhr.response));
          } else if (xhr.readyState === 4) {
            callBack('could not fetch data');
          }
        });
      
        xhr.open("GET", link);
        xhr.send();
      };
      
      moveiData(url, function (response) {
        console.log(response);
      
        moveiData(url, function (response) {
          console.log(response);
        });
      });
      

      【讨论】:

        猜你喜欢
        • 2011-12-08
        • 2013-03-29
        • 2015-01-10
        • 1970-01-01
        • 1970-01-01
        • 2023-03-28
        • 2020-08-08
        • 1970-01-01
        • 2012-09-27
        相关资源
        最近更新 更多