一、Promise
简单了解Promise的出现:
js代码执行顺序是从上到下的,然后有一些代码的执行的等待时间不确定例如:setTimeout,发送网络请求拿到结果等等(这些被称为异步任务),在这个等待的过程中,后续代码必须等到这些异步任务执行完成才会执行。这时候,我们想要拿到上述代码的执行结果,eg:网络请求成功,返回数据,请求失败,拿到失败结果。这时候,我们需要设计一个用来处理异步任务的函数,函数在调用的时候需要传入成功的回调函数,失败的回调函数,传入的其他参数等等(回调函数:函数的参数是一个函数,这个作为参数的函数在函数内部进行调用,叫做回调函数)。设计这样一个函数,不同的人有不同的设计,所以Promise是一个规范。
1.1Promise的基本使用,Promise是一个类
// 1.创建一个Promise对象
const promise = new Promise((resolve, reject) => {
// 注意: Promise的状态一旦被确定下来, 就不会再更改, 也不能再执行某一个回调函数来改变状态
// 1.待定状态 pending
console.log("111111")
console.log("222222")
console.log("333333")
// 2.兑现状态 fulfilled
resolve()
// 3.拒绝状态 rejected
reject()
})
promise.then(value => {
console.log("成功的回调")
}).catch(err => {
console.log("失败的回调")
})
【Tips】
1.1.1通过new创建的Promise对象需要传入一个回调函数,这个回调函数会被立即执行
1.1.2这个回调函数的两个参数也是两个回调函数resolve,reject
1.1.3当我们调用resolve函数时,会执行Promise对象的then方法传入的回调函数
1.1.4当我们调用reject函数时,会执行Promise对象的catch方法传入的回调函数
1.2.Promise的实例方法
1.2.1then方法
它其实是放在Promise的原型上的 Promise.prototype.then
const promise = new Promise((resolve, reject) => {
resolve("success")
reject("failure")
})
// 1.then参数的传递方法: 可以传递两个参数
promise.then(res => {
console.log("成功的回调:", res)
}).catch(err => {
console.log("失败的回调:", err)
})
//这种写法也可以
promise.then(res => {
console.log("成功回调~", res)
}, err => {
console.log("失败回调~", err)
})
1.2.2catch方法
它其实是放在Promise的原型上的 Promise.prototype.catch
1.2.3finally方法
finally是在ES9(ES2018)中新增的一个特性:表示无论Promise对象无论变成fulfilled还是rejected状态,最终都会被执行
的代码。
const promise = new Promise((resolve, reject) => {
resolve("aaaa")
// reject("bbbb")
})
// 为什么可以这样写:因为promise.then本身返回一个promise对象,所以可以链式调用
promise.then(res => {
console.log("then:", res)
foo()
}).catch(err => {
console.log("catch:", err)
foo()
}).finally(() => {
console.log("哈哈哈哈")
console.log("呵呵呵呵")
})
function foo() {
console.log("哈哈哈哈")
console.log("呵呵呵呵")
}
1.3Promise的类方法
1.3.1Promise.resolve
Promise.resolve的用法相当于new Promise,并且执行resolve操作
const studentList = []
const promise = Promise.resolve(studentList)
promise.then(res => {
console.log("then结果:", res)
})
// 相当于
new Promise((resolve) => {
resolve("Hello World")
})
1.3.2 Promise.reject
reject方法类似于resolve方法,只是会将Promise对象的状态设置为reject状态
1.3.3Promise.all
它的作用是将多个Promise包裹在一起形成一个新的Promise
当所有的Promise状态变成fulfilled状态时,新的Promise状态为fulfilled,并且会将所有Promise的返回值组成一个数组;
当有一个Promise状态为reject时,新的Promise状态为reject,并且会将第一个reject的返回值作为参数
// 创建三个Promise
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve("p1 resolve")
reject("p1 reject error")
}, 3000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p2 resolve")
}, 2000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p3 resolve")
}, 5000)
})
// all:全部/所有
Promise.all([p1, p2, p3]).then(res => {
console.log("all promise res:", res)
}).catch(err => {
console.log("all promise err:", err)
})
二、async和await
2.1异步函数
async关键字用于声明一个异步函数
async function foo() {
console.log("foo function1")
console.log("foo function2")
console.log("foo function3")
}
foo()
const bar = async function() {}
const baz = async () => {}
class Person {
async running() {}
}
2.2异步函数的返回值:
2.2.1 没有返回值默认是undefined
2.2.2 返回一个普通的值 (字符串,对象,数组),相当于被包裹到Promise.resolvezhong
2.2.3 返回一个Promise,状态由Promise决定
2.2.4如果返回一个对象,并且实现了thenable,那么会由对象的then方法来决定
async function foo2() {
// 1.返回一个普通的值
// -> Promise.resolve(321)
return ["abc", "cba", "nba"]
// 2.返回一个Promise 3秒后拿到aaa
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("aaa")
}, 3000)
})
// 3.返回一个thenable对象
return {
then: function(resolve, reject) {
resolve("bbb")
}
}
}
foo2().then(res => {
console.log("res:", res)
})
2.3异步函数的异常
因为异步函数的返回值和Promise相关,异步函数中的异常可以通过.catch捕获到
3.1await关键字的使用
await后面是一个表达式,这个表达式会返回一个Promise,那么await会等到Promise的状态变成fulfilled(resolve)状态,之后会执行异步函数。
// 2.await关键字
// await条件: 必须在异步函数中使用
function bar() {
console.log("bar function")
return new Promise(resolve => {
setTimeout(() => {
resolve(123)
}, 100000)
})
}
async function foo() {
console.log("-------")
// await后续返回一个Promise, 那么会等待Promise有结果之后, 才会继续执行后续的代码
const res1 = await bar()
console.log("await后面的代码:", res1)
const res2 = await bar()
console.log("await后面的代码:", res2)
console.log("+++++++")
}
foo()
如果Promise的状态是reject,我们可以通过.catch捕获异常