前言
javascript 是单线程; 浏览器是多线程;所有异步解决方案归根结底都是回调形式。
1.Promise基本使用及本质
let p1 = new Promise((resolve, reject) => {
let arr = [1,2,3,4,5];
let arr1 = arr.filter(item => item > 3);
setTimeout(() => {
resolve(arr1);
}, 1000)
})
p1.then(res => {
console.log(res);
},err => {
console.log(err);
})
-
promise本质上是一个状态机,他的状态变化时单向的,也就是说他只能从pending(等待中)->resolve(已完成fulfilled),或者pending->rejected(已拒绝);
-
then方法有两个参数,分别对应两种改变后状态(resolve)和(reject)
2.then链式调用
const p1 = new Promise((resolve, reject) => {
let arr = [1,2,3,4,5];
let arr1 = arr.filter(item => item > 3);
setTimeout(() => {
resolve(arr1);
}, 1000)
})
p1
.then(res => {
console.log(res)
//then回调中可以return一个Promise
return new Promise((resolve, reject) => {
let arr2 = [1,2,3];
setTimeout(() => {
resolve(arr2)
}, 1000);
})
})
.then(res => {
console.log(res)
//then回调中也可以return一个值
return 1
})
.then(res => {
console.log(res)
})
//
//[4,5];
//[1,2,3];
//1
3.async/await基本使用
在处理多个彼此之间相互依赖的请求时候,promise的then方法显得过于累赘,此时用async/await就很轻便。
使用方法:
- 在函数前添加async,则在函数执行后自动返回一个Promise对象。
//eg1:
async function Person() {
}
let result = Person()
console.log(result);
//虽然Person方法无返回值,但result打印结果时Promise对象
//Promise {<resolved>: undefined}
//->__proto__: Promise
//->[[PromiseStatus]]: "resolved"
//->[[PromiseValue]]: undefined
//eg2:
async function Person() {
return 2
}
let result = Person()
console.log(result);// Promise {<resolved>: 2}
//Promise {<resolved>: 2}
//->__proto__: Promise
//->[[PromiseStatus]]: "resolved"
//->[[PromiseValue]]: 2
- await 必须在async函数里面使用,不能单独使用。
async function Person() {
let result = await Promise.resolve('success')
console.log(result)
}
Person()
- await 后面需要跟随Promise对象,不然没有意义,此时Promise对象后面不需要写then了, 因为await作用就是获取Promise对象的成功状态传递出的参数
function ret() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
})
})
}
async function test() {
let result = await ret() //因为fn会返回一个Promise对象
console.log(result) //这里会打出Promise成功后传递过来的'success'
}
test()
4.async/await错误处理方式
关于错误处理,由于await接受的是Promise成功状态的参数,则需要用到try catch来捕捉错误。
function ret (num){
return new Promise((resolve, reject) => {
setTimeout(() => {
if (num >= 100) {
resolve('success')
} else {
reject('failed')
}
}, 1000)
})
}
async function test() {
let result = await ret(222)
return result //由于await接受的是Promise成功状态的参数,如果失败了,跳到catch
}
test().then(response => {
console.log(response)
}).catch(error => {
console.log(error)
})
async/await
在async函数中使用await,那么await里面的代码就是同步,只有等await后面的Primise代码执行完,才可以继续往下一行执行,虽然同步代码,但也阻塞代码。
function fn(name) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${name}成功`)
}, 1000)
})
}
async function test() {
let p1 = await fn('小红')
let p2 = await fn('小明')
let p3 = await fn('小华')
return [p1, p2, p3]
}
test().then(result => {
console.log(result)
}).catch(result => {
console.log(result)
})
Demo
promise
function request(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(time)
}, time)
})
}
request(500).then(result => {
return request(result + 1000)
}).then(result => {
return request(result + 1000)
}).then(result => {
console.log(result)
}).catch(error => {
console.log(error)
})
转换成async/await
function request(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(time)
}, time)
})
}
async function getResult() {
let p1 = await request(500)
let p2 = await request(p1 + 1000)
let p3 = await request(p2 + 1000)
return p3
}
getResult().then(result => {
console.log(result)
}).catch(error => {
console.log(error)
})