You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的JavaScript函数在回调场景下被判定为非函数?

问题分析与解决

核心问题拆解

1. 函数返回值缺失

你的xhrcall函数本身没有任何return语句,所以调用xhrcall()时,默认返回undefined。你在xhr.onload箭头函数里写的return x,只属于这个箭头函数,和外层的xhrcall无关——这个return的结果只会被XMLHttpRequest的内部逻辑接收,不会成为xhrcall的返回值。

这就是为什么:

  • let fn = xhrcall()会得到undefined
  • window.callback = xhrcall()是把undefined赋值给了window.callback,调用callback()自然会报错“不是函数”

2. 异步操作的特性

XMLHttpRequest是异步操作,xhr.send()之后代码会继续执行,不会等请求完成。onload回调要等服务器响应回来才会触发,所以你没法通过同步的return直接拿到请求结果。


修正方案

方案一:用Promise封装异步逻辑(推荐)

把请求逻辑包裹在Promise里,通过resolve和reject传递异步结果:

function xhrcall() {
  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.responseType = "json";
    xhr.open("POST", "/api", true);
    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xhr.send("token=xxxxxxx");
    
    xhr.onload = () => {
      xhr.status === 200 ? resolve(xhr.response) : reject(false);
    };
    
    // 处理请求错误的情况
    xhr.onerror = () => {
      reject(false);
    };
  });
}

// 使用方式1:用.then()处理结果
xhrcall().then(result => {
  console.log("请求成功结果:", result);
}).catch(error => {
  console.log("请求失败:", error);
});

// 使用方式2:在async函数里用await(更直观)
async function fetchData() {
  try {
    const result = await xhrcall();
    console.log("请求成功结果:", result);
  } catch (error) {
    console.log("请求失败:", error);
  }
}
fetchData();

方案二:直接使用函数引用作为回调

如果你只是想把xhrcall作为回调函数使用(不关心返回结果),要赋值函数本身,而不是调用它的结果:

// 赋值函数引用,不是调用结果
window.callback = xhrcall;
// 现在调用callback()就是执行xhrcall函数,不会报错
callback();

内容的提问来源于stack exchange,提问作者MC888 Team

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 22:30:02