目录
async 和 await 解决回调地狱
Promise 封装异步代码
=========================================================================
认识 Promise
+ 是一个 ES6 出现的语法
+ Promise 也是一个 JS 内置的构造函数
+ Promise 翻译来就是承诺的意思
承诺有多少个状态 ?
=> 继续(执行)
=> 成功
=> 失败
=> 承诺状态的转换只能有一次
-> 要么是 继续转换成 成功
-> 要么是 继续转换成 失败
Promise 也有三个状态
=> 继续: pending
=> 成功: fulfilled
=> 失败: rejected
Promise 的基础语法
=> const p = new Promise(function a() {
// 你要封装的异步代码
})
=> promise 对象可以调用两个方法
1. p.then(function () {})
2. p.catch(function () {})
=> a 函数可以接受两个参数
1. 第一个参数: 可以将该 Promise 的状态转换为 成功
2. 第二个参数: 可以将该 Promsie 的状态转换为 失败
异步代码
const p = new Promise(function (resolve, reject) {
// 当你书写 resolve() 的时候, 就是在把 该 promsie 的状态转换为成功
// 执行 then 的时候书写的 b 函数
// 当你书写 reject() 的时候, 就是在把 该 promise 的状态转换为失败
// 执行 catch 的时候书写的 c 函数
// 书写异步代码
var time = 1000 * Math.round(Math.random() * 5 + 1)
console.log('承诺一辈子在一起')
setTimeout(() => {
if (time >= 3000) {
// 当做成功, 两人死了, 埋一个坟
// 通知一下, 你该烧纸了
// resolve() 调用的是 then 内部的函数 b
// 所以这里书写在 () 内部的内容就是给 b 的实参
resolve(time)
} else {
// 当做失败, 离婚
// 通知一下, 该去炸坟了
// reject() 调用的是 catch 内部的函数 c
// 所以这里书写在 () 内部的内容就是给 c 的实参, 也是报错信息
reject(time)
}
}, time)
})
promise 对象调用的两个方法
调用上面函数的两个方法
成功时执行的函数
p.then(function b(t) {
// 函数b 不会被直接调用的
// 会在 p 这个 promise 的状态转换成 成功 的时候调用
console.log(t, '成功的函数 b')
})
失败时执行的函数
p.catch(function c(err) {
// 函数c 不会被直接调用
// 会在 p 这个 promise 的状态转化成 失败 的时候调用
console.log(err, '失败的函数 c')
})
=========================================================================
Promise 进阶
+ 当一个 Promise 的 then 内的代码
+ 只要你在第一个 then 里面返回 return 一个新的 promise 对象
+ 新promise 对象的 then 可以在第一个 then 后面连续书写
对 ajax 进行二次封装
// 对 ajax 进行 二次封装
function pAjax(options = {}) {
const p = new Promise((resolve, reject) => {
// 执行 ajax
ajax({
url: options.url,
data: options.data,
token: options.token,
async: options.async,
method: options.method,
dataType: options.dataType,
success: function (res) {
resolve(res)
}
})
})
// 把我的 promise 对象返回出去
return p
}
// 此时的全局变量 a 和 pAjax 内的 局部变量 p 是一模一样的东西
// const a = pAjax({ url: '/xxx', data: 'xxx', dataType: 'xxxx' })
// a.then(res => {})
需求:
1. 发送请求到 /test/first
2. 发送请求到 /test/second
=> 前提: 必须要等到第一个请求结束以后再次发送
3. 发送请求到 /test/third
=> 前提: 必须要等到第二个请求结束以后再次发送
// 使用我按照 promise 形式封装的 pAjax 函数来完成
pAjax({ url: 'http://localhost:8888/test/first' })
.then(res => {
console.log('第一个请求结束了')
console.log(res)
// return 一个新的 promise 对象
return pAjax({
url: 'http://localhost:8888/test/second',
dataType: 'json'
})
})
.then(res => {
console.log('第二个请求结果')
console.log(res)
// return 一个新的 promise 对象
return pAjax({
url: 'http://localhost:8888/test/third',
data: 'name=Jack&age=20',
dataType: 'json'
})
})
.then(res => {
console.log('第三次请求的结果')
console.log(res)
})
=========================================================================
async 和 await 关键字
+ ES7 以后的语法
+ 为了解决 Promise 的问题
+ 核心作用: 把 异步代码 写的 看起来像 同步代码, 本质还是异步
async 关键字
+ 使用: 书写在函数的前面
=> async function () {}
=> async () => {}
+ 作用:
1. 该函数内可以使用 await 关键字了
2. 把该函数变成 异步函数, 只是叫做 异步函数
=> 影响的是函数内部的代码
await 关键字
+ 要求:
1. await 后面的内容必须是一个 promise 对象
2. await 必须写在一个有 async 关键字的函数内部
+ 作用:
=> 可以把 promise 中本该在 then 内的代码直接定义变量接受
=> 后续的代码需要等到 promise 执行完毕才会执行
console.log('start')
async function fn() {
// 此时 fn 函数内可以使用 await 关键字了
// pAjax 返回出来的 promise 对象会执行
// 把 resolve() 的时候 括号里面的内容 赋值给 r1. 在继续向后执行代码
const r1 = await pAjax({ url: 'http://localhost:8888/test/first' })
console.log(r1)
// 需求2:
const r2 = await pAjax({
url: 'http://localhost:8888/test/second',
dataType: 'json'
})
console.log(r2)
// 需求3:
const r3 = await pAjax({
url: 'http://localhost:8888/test/third',
data: 'name=Jack&age=20',
dataType: 'json'
})
console.log(r3)
}
fn()
console.log('end')