-
Promise 有三个状态:
pending
准备/挂起阶段resolve
成功,调用resolve()
reject
失败,调用reject()
resolve
和resolve
状态是唯一的且不可逆。
-
基本写法:
new Promise((resolve,reject)=>{ // resolve() // reject() }) .then(data=>{ //resolve状态执行这里 },err=>{ //reject状态执行这里 })
-
.then
- 返回值也是一个
Promise
,且默认返回的Promise
的状态为resolve
- 返回值也是一个
-
封装一个Ajax请求
ajax(`http://localhost:3000`) .then(res => { console.log(res.message) return ajax(`http://localhost:3000/date`) }) .then(res=>{ console.log(res) }) function ajax(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest() xhr.open('GET', url) xhr.send() xhr.onload = function () { if (this.status === 200) { resolve(JSON.parse(this.response)) } else { reject(new Error('请求失败')) } } xhr.onerror = function () { reject(new Error('请求失败')) } }) }
-
封装一个
jQeury.Ajax
请求ajax(`http://localhost:3000`) .then(res => { console.log(res.message) return ajax(`http://localhost:3000/date`) }) .then(res=>{ console.log(res) }) function ajax(url) { return new Promise((resolve, reject) => { $.ajax({ url, type: 'get', success: resolve, error: reject }) }) }
-
axios
因为自身就用Promise
封装,所以直接写就可以了axios.get('http://localhost:3000') .then(res => { console.log(res.data.message) return axios.get('http://localhost:3000/date') }) .then(res => { console.log(res.data) })
-
Promise.all
- 批量处理
Promise
,返回值为resolve
的值组成的数组
const baseUrl = `https://game.gtimg.cn/images/lol/act/img/js/` //请求英雄列表 function getHeroList(url) { return axios.get(url) } //请求单个英雄资料 function getHeroById(url, id) { return axios.get(`${url}hero/${id}.js`) } getHeroList(baseUrl + 'heroList/hero_list.js') .then(res => { const arr = [] for (item of res.data.hero) { arr.push(getHeroById(baseUrl, item.heroId)) } return Promise.all(arr) }) .then(res => { for (item of res){ console.log(item.data.hero); } })
- 批量处理
-
Promise.all
解决错误的方法- 一旦遇到任意一个
Promise
为reject
状态,并且这个Promise
没有catch
,那么立即停止批量行为并返回将自身变为reject
状态;而如果这个Promise
有catch
,则不会停止批量行为,但是会返回一个undefined
,因为这个Promise
的reject
被catch
,默认返回的是一个resolve
的Promise
,但是不带有数据。
let p1 = new Promise((resolve, reject) => { setTimeout(resolve(1), 1000) }) let p2 = new Promise((resolve, reject) => { setTimeout(resolve(2), 2000) }) let p3 = new Promise((resolve, reject) => { reject(3) }) .catch(reason=>{ console.log(3) }) let p4 = new Promise((resolve, reject) => { setTimeout(resolve(4), 4000) }) let p5 = new Promise((resolve, reject) => { setTimeout(resolve(5), 5000) }) Promise.all([p1, p2, p3, p4, p5]) .then(res => { console.log(res) } ) .catch(err => { console.log(err) }) //输出结果 : [1,2,undefined,4,5]
- 一旦遇到任意一个
-
Promise.AllSettled
- 用法与
Promise.all
大致相同,只不过reject
状态的Promise
不会停止批量操作,且得到的数组中每一项都会有一个status
属性来记录是否状态。
- 用法与
-
Promise.race
- 参数也是
Promise
数组,但是返回值是一个Promise
,它是最早变为resolve
状态的那个Promise
- 参数也是
-
语法糖
async&await
- 下面的例子中,三者的写法是等价的。如果返回的值是直接量,
async
会将函数包装为一个resolve
状态的Promise
。
async function test1() { return 'async test' } function test2() { return Promise.resolve('Promise.resolve test') } function test3() { return new Promise(resolve => { resolve('new Promise test') }) } console.log(test1()) console.log(test2()) console.log(test3()) /* Promise { 'async test' } Promise { 'Promise.resolve test' } Promise { 'new Promise test' } */
await
等待一个表达式返回的值,如果返回的值为直接量,await
会利用Promise.resolve
把它包装为一个Promise
;如果返回的值为Promise
,那么不会做处理;表达式是异步的,则会等待异步完成之后,再往下面进行;如果表达式是同步的,则会立即返回。
function test1(n) { return new Promise(resolve => { setTimeout(function () { resolve(n + 1) }, 1000) }) } function test2(n) { return new Promise(resolve => { setTimeout(function () { resolve(n + 2) }, 2000) }) } function test3(n) { return new Promise(resolve => { setTimeout(function () { resolve(n + 3) }, 3000) }) } async function main() { const n1 = await test1(1) console.log(n1) //2 const n2 = await test2(n1) console.log(n2) //4 const n3 = await test3(n2) console.log(n3) //7 } main()
- 下面的例子中,三者的写法是等价的。如果返回的值是直接量,
-
推荐边城老师的理解 JavaScript 的 async/await
Promise详解
最新推荐文章于 2022-08-09 07:18:23 发布