TypeScript中async函数返回非Promise值为何调用仍需await?
getData()为什么必须加await 核心结论:只要函数/方法被async关键字标记,无论内部return的是什么类型的值,对外的返回值永远会被自动包装为Promise实例,必须用await或者.then()才能拿到return的实际业务值。
首先搞懂
async的返回值包装规则
你代码里虽然写的是return this._initialNames,看起来返回的是reduce处理后的结果,但只要加了async标记,JS/TS引擎会自动把返回值包一层Promise。举个最直观的最简例子:async function demo() { return { a: 1 } } const res = demo() console.log(res) // 打印结果是 Promise {<fulfilled>: {a:1}},不是普通对象{a:1}你的
getData()遵循完全一样的逻辑,对外返回的永远是Promise,不是你以为的数组(顺带纠正:你代码里reduce的初始值是空对象{},最终生成的_initialNames是键为name属性的映射对象,不是数组)。其次搞懂
async/await的作用边界
你知道内部用await调用fetch必须给方法加async是对的,但要注意:await的暂停阻塞效果只在当前async函数内部生效,不会改变函数本身异步执行的本质,更不会把异步方法变成同步方法给外部调用方用。
你可以把async/await理解成Promise链式调用的语法糖:它只是帮你把方法内部原本要写的.then(resp => resp.json())这类嵌套回调改成了类似同步的写法,不会让方法对外变成同步返回。
如果你调用时不加await,会立刻拿到一个还在pending状态的Promise,根本拿不到fetch返回后处理好的数据;甚至你调用getData()之后立刻去读实例上的_initialNames属性,大概率还是undefined——因为此时fetch请求还没返回,reduce赋值的逻辑根本还没执行到。调用写法的对错对比
错误写法(不加await):const result = instance.getData() console.log(result) // 拿到的是Promise实例,不是业务数据 console.log(instance._initialNames) // 大概率是undefined,赋值逻辑还没执行正确写法1(await):
const result = await instance.getData() console.log(result) // 拿到reduce生成的name映射对象,和实例上的_initialNames是同一个值正确写法2(.then(),和await效果等价):
instance.getData().then(result => { console.log(result) // 回调触发时才能拿到实际业务数据 })
内容的提问来源于stack exchange,提问作者sal3jfc

