1272 字
6 分钟

then(),关键字async和await

欢迎来到我的博客!#

使用 Markdown 格式编写。

今天学到了什么#

  • then(箭头函数)

    then是一个方法,形参是一个函数,我这是在调用then这个方法

  • async和await

  • await详解

then()#

这是一个非常容易混淆的知识点!你混淆了 “回调函数的返回值”then() 方法本身的返回值”

注释里说的 // then()原地的结果是一个新的Promise对象 是完全正确的。

你可以这样理解:

  1. then() 方法本身永远都会返回一个新的 Promise 对象: 不管你在 then() 的回调函数内部写了什么,哪怕你什么都不写,p.then(...) 这个表达式执行完后,原地留下的一定是一个全新的 Promise 对象(这也是为什么你能一直 .then().then() 链式调用的根本原因)。

  2. 你写的 return 仅仅是用来决定这个“新 Promise”的最终结果是什么

    • 如果你不写 return (默认返回 undefined)then() 返回的那个新 Promise 依然存在,只不过它的状态会自动变成成功(fulfilled),自带的数据是 undefined
    • 如果你 return 了一个普通字符串/数字then() 返回的新 Promise 状态变成成功,自带的数据是你 return 的字符串/数字。
    • 如果你写了 return new Promise(...)then() 返回的新 Promise 会被“替换”或“接管”。它会等待内部这个 new Promise 执行完毕,内部是成功它就跟着成功,内部是失败它就跟着失败。

验证一下: 你可以尝试把那个 return new Promise(...) 删掉或者注释掉,只保留 console.log(result),你会发现最后的 console.log(p2 === p) 依然是 false,而且你可以打印一下 console.log(p2),你会看到它依然是一个 Promise 对象,仅仅是它内部的 PromiseResult 变成了 undefined

换句话说:没写 return 导致拿到 undefined 的是下一次 then() 里面接收的参数,而不是外层 then() 创造出来的对象。

async和await#

是的,这完全是 JavaScript 的原生基本语法,属于 ES8(ECMAScript 2017)引入的标准。它没有任何魔法,也不需要借助第三方库,浏览器原生就支持。

它本质上是 Promise 的“语法糖”(换一种更甜、更舒服的写法),底层机制依然是你刚才学的 Promise。

  • async(异步的):写在 function 前面,把一个普通函数声明为“异步函数”。(顺带一提,被 async 修饰的函数执行后,无论里面写什么,一定会默认返回一个 Promise 对象)。
  • await(等待):只能写在 async 函数的内部。它的作用就像一个暂停键。当代码执行到 await axios(...) 时,这个函数内部的代码会暂停往下走,死死盯住右边这个 Promise。直到它请求成功,await 就会直接把成功拿到的数据(也就是原来 .then(res => ...) 里的那个 res)剥离出来,赋值给左边的变量 pObj,然后代码才继续往下走。

为什么要引入这种语法? 刚才你理解 .then()return new Promise 时,是不是觉得传来传去、套来套去还是有点绕? async / await 就是为了彻底消灭回调函数。它让你能够用极其直观的、从上到下一行一行的“同步代码”格式,来编写实际上是异步的代码。

await详解:axios返回的不是一个promise对象吗?那这个变量为什么是then函数中的res?#

你的前半句理解得完全正确:axios(...) 本身执行完毕后,确实是返回了一个 Promise 对象。

但是,当你在一个 Promise 对象前面加上 await 关键字时,JS 引擎会帮你做一层“魔法转换”:

  1. 暂停与等待: await 会让当前这个 async 函数暂停往下执行,留在原地“死等”这个 Promise 对象的结果。
  2. 自动解包获取结果: 当这个 Promise 处于成功状态时,await 会自动把 Promise 里那个成功的数据提取出来(也就是你以前在 .then(res => {...}) 里拿到的那个 res),然后赋值给等号左边的变量 pObj

你可以把 await 想象成一个“吸星大法”或者“开箱器”:它专门负责把 Promise 盒子拆开,直接把里面的成功结果丢给你。

我们来做个直观的对比,这两种写法的最终目的完完全全是一样的:

以前的写法(用 then):

axios({url: 'http://hmajax.itheima.net/api/province'})
.then(pObj => { // 成功的结果赋值给了形参 pObj
console.log(pObj)
})

现在的写法(用 async/await):

// await 直接把解析出来的成功结果,赋值给了变量 pObj
const pObj = await axios({url: 'http://hmajax.itheima.net/api/province'})
console.log(pObj)

总结: 这叫做**“语法糖”。因为天天写 .then().then().then() 嵌套回调函数太恶心了(回调地狱),所以 JS 官方发明了 await。它让你能用写同步代码的格式,去写异步代码**。它底层依然是 Promise 和 then,只是 JS 帮你在表面上把它精简成了等号赋值的样子。

赞助支持

如果这篇文章对你有帮助,欢迎赞助支持!

赞助
then(),关键字async和await
https://firefly.cuteleaf.cn/posts/study-everyday/2026-03-08今日学习-then关键字async和await/
作者
LJC
发布于
2026-03-08
许可协议
CC BY-NC-SA 4.0
最后更新于 2026-03-08,距今已过 12 天

部分内容可能已过时

目录