Node.js中使用Async/Await提示returnone is not a function,求排查
问题分析:变量提升导致的函数未定义错误
你遇到的问题核心是JavaScript的变量提升机制在搞鬼,咱们一步步拆解清楚:
- 你用
var声明了returnone作为函数表达式,虽然var会把变量名提升到当前作用域顶部,但它只提升了变量本身,并没有把后面的函数赋值逻辑也提前。 - 当代码执行到
var testasync = async () => {...}这一行时,testasync内部要调用returnone(),但此时returnone还只是一个被提升的空变量(值为undefined),还没被后面的代码赋值为那个返回Promise的函数,所以自然会抛出returnone is not a function的错误。 - 而你单独执行
returnone().then(...)时,整个代码已经执行完毕,returnone早就被赋值为目标函数,所以能正常运行。
修复方案
有几种简单且实用的解决方法:
方法1:调整代码顺序,提前定义returnone
直接把returnone的定义移到testasync前面,确保调用前函数已经存在:
var returnone = () => { return new Promise((resolve,reject)=> { setTimeout(()=>{ resolve('1'); },2000) }) } var testasync = async () => { const result1 = await returnone(); return result1; } testasync().then((name)=>{ console.log(name); }).catch((e) =>{ console.log(e); });
方法2:改用函数声明替代函数表达式
函数声明会被完全提升到作用域顶部,不管写在哪个位置,都能在作用域内被提前调用:
var testasync = async () => { const result1 = await returnone(); return result1; } testasync().then((name)=>{ console.log(name); }).catch((e) =>{ console.log(e); }); // 改用函数声明形式 function returnone() { return new Promise((resolve,reject)=> { setTimeout(()=>{ resolve('1'); },2000) }) }
方法3:使用let/const替代var(更推荐)
let和const不存在变量提升到作用域顶部的特性,而且它们的暂时性死区会强制你先定义再使用,能从根源避免这类时序问题:
const returnone = () => { return new Promise((resolve,reject)=> { setTimeout(()=>{ resolve('1'); },2000) }) } const testasync = async () => { const result1 = await returnone(); return result1; } testasync().then((name)=>{ console.log(name); }).catch((e) =>{ console.log(e); });
内容的提问来源于stack exchange,提问作者alangilbi
相关产品推荐
相关产品推荐

