async 函数
- Generator 函数的语法糖 使异步操作更简略
async
示意函数里有异步操作,await
示意紧跟在前面的表达式须要期待后果。-
返回值 一个 Promise 对象,能够用 then 办法指定下一步操作
- async 函数 return 的值通过 Promise 对象 resolved 时候的 data 获取
- async 函数 throw 的谬误通过 Promise 对象 rejected 时候的 error 获取
async function test() {return 1;}
const p = test();
console.log(p); // Promise {<resolved>: 1}__proto__: Promise[[PromiseStatus]]: "resolved"[[PromiseValue]]: 1
p.then(function(data) {console.log(data); // 1
});
async function test() {throw new Error("error");
}
const p = test();
console.log(p); // Promise {<rejected>: Error: error...}
p.catch(function(err) {console.log(err); // Error: error
});
await
- await 命令只能用在 async 函数之中
- await 后能够是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会主动转成立即 resolved 的 Promise 对象)
- await 后 Promise 对象状态变为 rejected,后续执行中断
await 后 Promise 对象状态为 resolved
async function async1() {console.log("async1 start");
let r = await async2();
console.log(r)
console.log("async1 end");
}
async function async2() {return Promise.resolve().then(_ => {console.log("async2 promise");
return "value from async2"
});
}
async1();
- 执行 async1,打印 ”async1 start”
- 执行 await async2(),await 会期待 Promise 变成 resolved 状态,而后拿到返回值,因而会执行 Promise.resolve().then(),打印 ”async2 promise”
- async2 中 then 函数返回的值被赋值给 r,打印 ”value from async2″
- 打印 ”async1 end”
await 后 Promise 对象状态为 reject
await Promise.reject(“error”)后的代码不会被执行
async function f() {await Promise.reject("error");
console.log(1);
await 100;
}
f();
解决异样后,前面的代码就会执行了
-
通过 Promise 对象的
catch
办法async function f() {await Promise.reject("error").catch(err => {// 解决异样}); console.log(1); await 100; } f();
-
通过 try{}catch{}捕捉异样
async function f() { try {await Promise.reject("error"); } catch {// 解决异样} console.log(1); await 100; } f();
实现原理
Generator + 主动执行器
// 应用 async 函数 返回 Promise 对象
async function example(params) {// ...}
// 实现
function example(params) {return spawn(function*() {// ...});
}
function spawn(genF) {return new Promise(function(resolve, reject) {const gen = genF(); // 生成器对象
function step(nextF) {
let next;
try {next = nextF(); // 执行 gen.next
} catch (e) {return reject(e);
}
if (next.done) {return resolve(next.value);
}
Promise.resolve(next.value).then(function(v) {step(function() {return gen.next(v);
});
},
function(e) {step(function() {return gen.throw(e);
});
}
);
}
step(function() {return gen.next(undefined);
});
});
}
利用
按程序打印文件
Promise 实现
function readFilesByPromise() {const fs = require('fs')
const path = require('path')
const files = [
'./file/a.json',
'./file/b.json',
'./file/c.json'
]
function readFile(url) {return new Promise((resolve, reject) => {fs.readFile(path.join(__dirname, url), function (err, data) {if (err) {reject(err) }
resolve(data)
})
})
}
readFile(files[0])
.then((data) => {console.log(data.toString())
return readFile(files[1])
})
.then((data) => {console.log(data.toString())
return readFile(files[2])
})
.then((data) => {console.log(data.toString())
})
}
readFilesByPromise()
async/await 实现
async function readFilesByAsync() {const fs = require('fs')
const path = require('path')
const files = [
'./file/a.json',
'./file/b.json',
'./file/c.json'
]
function readFile(url) {return new Promise((resolve, reject) => {fs.readFile(path.join(__dirname, url), function (err, data) {if (err) {reject(err) }
resolve(data)
})
})
}
const str1 = await readFile(files[0])
console.log(str1.toString())
const str2 = await readFile(files[1])
console.log(str2.toString())
const str3 = await readFile(files[2])
console.log(str3.toString())
}
readFilesByAsync()