1. 前言
- 首先说明
async/await
语法 属于ES7
,不过到现在就算是es6也还算是新技术吧,技术迭代比较慢- 其实这个
async/await
也是一种语法糖
2. 是什么 what
async/await
语法 通常结合promise
使用- 也就是说也是用同步的方式来写异步代码
async
是异步的意思 用来声明一个function
是异步的await
是 async wait 异步等待 ,就是等待一个异步函数执行完成- 规定
await
只能出现在async
函数中
3. async 基础
3.0 准备工作
function testAsy() {
"hello asy"
}
const result = testAsy()
console.log("result:",result);
- 正常函数 不写返回值 结果是 undefined
- 运行结果
3.1 async -无返回值
async function testAsy() {
"hello asy";
}
const result = testAsy();
console.log("result:", result);
- 返回结果变为 空
Promise
, 证明async
会把函数结果变为Promise
- 运行结果
- 既然是
pomise
了那resolve
的结果是啥呢
async function testAsy() {
"hello asy";
}
// const result = testAsy();
// console.log("result:", result);
testAsy().then(res=>{console.log("-----------------1",res)})
- 运行结果
undefined
async
修饰的函数 是异步函数async
内部给函数包了一层Promise.resolve()
3.2 async - 有返回值
async function testAsy() {
return "hello asy";
}
testAsy().then(res=>{console.log("-----------------1",res)})
- 函数的返回值是任何数据(数组,对象),则得到一个非空的
promise
对象,resolve
数据是返回的数据- 运行结果
3.3 async- 返回 Promise
async function testAsy() {
return new Promise((resolve) => {
resolve("玩呗");
});
}
testAsy().then((res) => {
console.log("-----------------1", res);
});
- 直接得到返回值
- 运行结果
3.4 总结
- async函数的返回值总是一个promise对象, 有以下三种情况
- 如果没有写返回值, 则得到一个空的promise对象, resolve数据是 undefined,
- 如果返回值是数据,则得到一个非空的peomise对象, resolve数据是返回的数据,
4. reject实现
- 既然有
resolve
那肯定也有reject
4.1 代码
async function testAsy(flag) {
if(flag){
return "hello asy"
}else{
throw '抛出异常'
}
}
console.log(testAsy(true));//Promise.resolve()
console.log(testAsy(false));//Promise.reject()
4.2 结果
5. catch
5.1 代码
async function testAsy(flag) {
if(flag){
return "hello asy"
}else{
throw '抛出异常'
}
}
testAsy(false).then(res=>{
console.log("Res:",res);
}).catch(err=>{
console.log("捕获错误:",err);
})
5.2 结果
还是通过 promise的 catch来进行错误捕获
6. await catch
6.0 await
await
放在一个Promise
对象前,
会等待Promise
异步结果,
然后以返回值的形式拿到异步结果,
使异步结果更简单方便的获取,
- 避免了回调的嵌套结构,
- 省略了then函数调用
- 后面可以跟任何表达式
6.1 为什么await可以使用同步返回值的形式拿到异步promise的结果
await
通过阻塞进程,使同步代码暂停执行, 等Promise
异步任务得到结果后,继续执行同步指令,- 所以,(await is only valid in async function await)仅允许在异步函数中使用,
- 他只会阻塞异步函数中的同步代码, 不会阻塞整个进程)
6.2 练习题 await 同步语法练习
- 练习
var p = new Promise(function(resolve){
setTimeout(() => {
resolve("成功")
}, 100);
})
// 正常情况下, 一般在promise对象的then方法的回调中拿到结果
p.then(function(res){ console.log(res)} );
console.log("-------------", 0)
async function fun(){
console.log(1)
var data = await p;
console.log(2)
console.log(3,data);
}
fun()
console.log(4)
输出
- 强化题
function testWait() {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("测试wait")
},1000)
})
}
async function test() {
const r1 = await testAsy(true)
console.log("结果 wait:",r1);
const r2 = await testWait()
console.log("结果 wait:",r2);
}
test()
6.2 分析
1.testWait()本身就是返回的promise,异步的,所以不需要加async
2.使用async/await语法对比
3.await
放置在Promise
调用之前,await
强制等待后面代码执行,直到Promise对象resolve,得到resolve的值作为await表达式的运算结果
4.await
只能在async
函数内部使用,用在普通函数里就会报错
6.3 then处理
await
直接脱掉了一层then的壳 比较方便
6.4 catch
function testWait() {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("测试wait")
},1000)
})
}
async function test() {
const r1 = await testAsy(true)
console.log("结果 wait:",r1);
const r2 = await testWait()
console.log("结果 wait:",r2);
try{
let res3 = await testAsy(false)
console.log("结果-3:",res3)
} catch(error){
console.log("-------",error)
}
}
test()
其实就是结合 try{}catch{}来搞
7.react 使用
async componentDidMount(){
try{
let res1 = await axios.get("/v1/use?type=1")
console.log("结果:",res1)
} catch(error){
console.log("-------",error)
}
8. vue3 使用
async created() {
this.characters = (await getList()).data
}
9. 多异步任务并发执行解决方案
// 异步函数用法举例:
var fs = require("fs")
var p1 = new Promise(function(resolve){
fs.readFile("./data/a.txt",function(err,data){
resolve(data)
})
})
var p2 = new Promise(function(resolve){
fs.readFile("./data/b.txt",function(err,data){
resolve(data)
})
})
var p3 = new Promise(function(resolve){
fs.readFile("./data/c.txt",function(err,data){
resolve(data)
})
})
var p4 = new Promise(function(resolve){
fs.readFile("./data/d.txt",function(err,data){
resolve(data)
})
})
// 多异步任务并发执行方案一: promise合并
var allP = Promise.all([p1,p2,p3,p4])
allP.then(function(res){
console.log(res.join(""))
})
// 多异步任务并发执行方案二: 异步函数
async function getData(){
var data1 = await p1;
var data2 = await p2;
var data3 = await p3;
var data4 = await p4;
console.log(data1 + data2 + data3 + data4)
}
getData()
10. 扩展下规范的几个阶段
1.编辑草案 Editor's Draft (ED)
2.工作草案 Working Draft (WD)
3.过渡-最后通告工作草案 Transition – Last Call Working Draft (LCWD)
4.候选推荐标准 Candidate Recommendation (CR)
5.过渡-建议推荐标准 Transition – Proposed 6.Recommendations (PR)
7.推荐标准 Recommendation (REC)
参考资料
promise-ajax封装
fetch基础
promise基础
vue3-ts-async