为何我的JavaScript函数在回调场景下被判定为非函数?
问题分析与解决
核心问题拆解
1. 函数返回值缺失
你的xhrcall函数本身没有任何return语句,所以调用xhrcall()时,默认返回undefined。你在xhr.onload箭头函数里写的return x,只属于这个箭头函数,和外层的xhrcall无关——这个return的结果只会被XMLHttpRequest的内部逻辑接收,不会成为xhrcall的返回值。
这就是为什么:
let fn = xhrcall()会得到undefinedwindow.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
相关产品推荐
相关产品推荐

