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]]: 1p.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()