Promies async await
- await 关键字接收一个Promise 当 resolve 时可以把这个值赋给表达式左边的变量
- 当 reject 的时候会抛出一个错误
- 如果不接受Promise也是可以运行的
- async返回一个Promise的值
async function get(id){
const url = 'https://zhanlan.zhihu.com/api/colums/${id}';
const response = await fetch(url);
return await response.json();
}
(async()=>{
const column = await get(20)
console.log(`NAME:${column.name}`)
console.log(`INTRO:${conlumn.intro}`)
})()
-
无论是在node里面还是在浏览器 的顶级作用域里面,使用async关键字是非法的
-
throw用来抛出异常, 把他和try catch一起使用,可以起到控制程序流,并生成自定义的错误信息
-
await 可以将值转成 Promise.resolve() 有一个这样的隐式转换
-
关于使用 try catch 容错处理的话是这样的,如果异步不写容错处理的话那么有一个 reject 会直接跳出,如果有容错处理的话,会在目标代码块内走容错处理的catch 而不对其他的 await 产生影响
let fetchDataA = () =>{
return new Promise((resolve,reject)=>[
setTimeout(()=>{
reject('fetch data is A')
},1000)
])
}
let fetchDataB = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('fetch data is B')
}, 1000)
})
}
let fetchDataC = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('fetch data is C')
}, 1000)
})
}
(async () => {
try {
const dataC = await fetchDataC()
console.log('dataC is ->', dataC)
} catch(err) {
console.log('err is ->', err)
}
try {
const dataA = await fetchDataA()
console.log('dataA is ->', dataA)
} catch(err) {
console.log('err is ->', err)
}
try {
const dataB = await fetchDataB()
console.log('dataB is ->', dataB)
} catch(err) {
console.log('err is ->', err)
}
})()
-
在 await 的使用中如果 走的是 reject 返回的是 catch 中 return 出来的值 ,如果走的是resolve的话那么取到的是then中返回的值
let fetchDataA = () =>{
return new Promise((resolve,reject)=>[
setTimeout(()=>{
reject('fetch data is A')
},1000)
])
}
(async () => {
let data = await fetchDataA().then(data => data ).catch(err => err + 'error');
console.log(data)
})()
-
另一种简化的错误处理方式
let fetchDataA = () =>{
return new Promise((resolve,reject)=>[
setTimeout(()=>{
reject('fetch data is A')
},1000)
])
}
let fetchDataB = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('fetch data is B')
}, 1000)
})
}
let fetchDataC = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('fetch data is C')
}, 1000)
})
}
(async () => {
let [errA, dataA] = await fetchDataA().then(data => [null, data] ).catch(err => [err+' error', null])
console.log(dataA)
let [errB, dataB] = await fetchDataB().then(data => [null, data] ).catch(err => [err+' error', null])
console.log(dataB)
let [errC, dataC] = await fetchDataC().then(data => [null, data] ).catch(err => [err+' error', null])
console.log(dataC)
})()
并行和串行
串行的方式
const fetch = require('node-fetch');
async function getZhihuColumn(id){
const url = `https://zhuanlan.zhihu.com/api/colums/${id}`;
const response = await fetch(url);
return await response.json();
}
const showColumnInfo = async ()=> {
const feweekly = await getZhihuColumn('feweekly');
const toolingtips = await getZhihuColumn('toolingtips');
console.log(`NAME: ${feweekly.name}`);
console.log(`INTRO: ${feweekly.intro}`);
console.log(`NAME: ${toolingtips.name}`);
console.log(`INTRO: ${toolingtips.intro}`)
}
showColumnInfo()
并行的方式
-
这种并行的方式并不算是严格意义上的并行,只是在一定程度上是并行的
-
在使用 await 处理请求放回回来的Promise的时候还是要等上一个执行完才进行下一个的请求
-
这样写节省了一部分,请求数据的时间
const fetch = require('node-fetch');
async function getZhihuColumn(id){
const url = `https://zhuanlan.zhihu.com/api/colums/${id}`;
const response = await fetch(url);
return await response.json();
}
const showColumnInfo = async ()=> {
const feweeklyPromise = getZhihuColumn('feweekly');
const toolingtipsPromise = getZhihuColumn('toolingtips');
const feweekly = await feweeklyPromise;
const toolingtips = await toolingtipsPromise;
console.log(`NAME: ${feweekly.name}`);
console.log(`INTRO: ${feweekly.intro}`);
console.log(`NAME: ${toolingtips.name}`);
console.log(`INTRO: ${toolingtips.intro}`)
}
showColumnInfo()
-
另一种使用Promise.all() 的并行方式
const fetch = require('node-fetch');
async function getZhihuColumn(id){
const url = `https://zhuanlan.zhihu.com/api/colums/${id}`;
const response = await fetch(url);
return await response.json();
}
const showColumnInfo = async ()=> {
const [feweekly,toolingtips] = await Promise.all([
await getZhihuColumn('feweekly'),
await getZhihuColumn('toolingtips')
])
console.log(`NAME: ${feweekly.name}`);
console.log(`INTRO: ${feweekly.intro}`);
console.log(`NAME: ${toolingtips.name}`);
console.log(`INTRO: ${toolingtips.intro}`)
}
showColumnInfo()
- Promise.all()
let wake = (time,type) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(type){
resolve(`${time / 1000}秒后醒来`)
}else {
reject(`${time / 1000}秒后返回错误`)
}
}, time)
})
}
let p1 = wake(1000,false)
let p2 = wake(6000,true)
Promise.all([p1, p2]).then((result) => {
console.log(result) // [ '3秒后醒来', '2秒后醒来' ]
}).catch((error) => {
console.log(error)
})
-
Promise.all() 接收一个数组,每项是一个Promise
-
执行的时候会在每一项都执行完以后,以数组的方式返回每项的结果
-
如果有一个Promise是失败的状态的话,那么并不会返回数据而是返回,失败的值
-
Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚
一个小经验
- 这种返回一个Promise的写法是可以使用asycn的性质的
function simulation(){
let res = new Promise((r,s)=>{
setTimeout(()=>{
r({suss:true})
},1200)
})
return res
}
async function jkl (){
let res = await simulation()
console.log(res)
}
jkl()