ES(2017)學習筆記(十一)【Async】
async
函式
async
函式屬於ES7
,是一個Generator
函式的語法糖。
async
函式可以自動執行Generator
函式。
async
函式的實現原理,就是將Generator
函式和自動執行器,包裝在一個函式裡。
async function fn(args) {
// ...
}
// 等同於
function fn(args) {
//spawn函式是自動執行器
return spawn(function* () {
// ...
});
}
//spawn函式的實現
function spawn(genF) {
return new Promise((resolve, reject) => {
let gen = genF();
function step(nextF) {
try {
var next = nextF();
} catch(e) {
return reject(e);
}
if(next.done) {
return resolve(next.value);
}
//使用Promise.resolve使其可以支援原始型別的值,保證返回一個Promise物件
Promise.resolve(next.value)
.then(v => step( () => gen.next(v) ) //呼叫後next.value作為結果返回
, e => step( () => gen.throw(e) ));
}
//呼叫step進行遞迴執行gen
step( () => gen.next(undefined) );
});
}
與co
模組使用的區別在於:
co
模組執行的Generator
函式的yield
語句後可以是Promise
物件或者Thunk
函式。async
函式await
後可以是Promise
物件或者原始型別的值(數值、字串和布林值,但這時等同於同步操作)。
const fs = require('fs');
const co = require('co');
//將非同步封裝到Promise
const readFile = function (fileName) {
return new Promise(function(resolve, reject) {
fs.readFile(fileName, function(error, data) {
if(error) return reject(error);
resolve(data);
})
});
};
//用生成器函式和co實現
const gen = function* (){
const f1 = yield readFile('/ect/f1');
const f2 = yield readFile('/ect/f2');
}
co(gen); //返回一個Promise物件
//用async函式實現
const asyncReadFile = async function() {
const f1 = await readFile('/ect/f1');
const f2 = await readFile('/ect/f2');
}
let result = asyncReadFile(); //返回一個Promise物件
一個例子,指定多少毫秒後輸出一個值。
function timeout(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value);
}
asyncPrint('hello world', 50);
async
的錯誤處理機制
async
函式的語法規則總體上比較簡單,難點是錯誤處理機制。
返回Promise
物件
async
函式返回一個Promise
物件。
async
函式內部return
語句返回的值,會成為then
方法回撥函式的引數。
async
函式內部丟擲錯誤,會導致返回的Promise
物件變為reject
狀態。
async function f() {
throw new Error('出錯了');
}
f().then(
v => console.log(v),
e => console.log(e) //被呼叫
)
// Error: 出錯了
返回的Promise
的狀態,必須等到內部所有await
命令後面的Promise
物件執行完,才會發生狀態改變,除非遇到return
語句或者丟擲錯誤。
await
命令後面的Promise
物件如果變為reject
狀態,則reject
的引數會被catch
方法的回撥函式接收到。
async function f() {
await Promise.reject('出錯了');
await Promise.resolve('hello world'); // 不會執行
}
f()
.then(v => console.log(v))
.catch(e => console.log(e))
// 出錯了
相關文章
- ES(2017)學習筆記(十)【Async】筆記
- ES(2017)學習筆記(十二)【Async】筆記
- async函式學習筆記。函式筆記
- ES[7.6.x]學習筆記(十一)與SpringBoot結合筆記Spring Boot
- ES6 學習筆記筆記
- ES6 學習筆記筆記
- es6學習筆記筆記
- hive學習筆記之十一:UDTFHive筆記
- Vue學習筆記(十一):路由管理Vue筆記路由
- angular學習筆記(十一)-表示式Angular筆記
- ES6 學習筆記四筆記
- ES6 學習筆記一筆記
- ES6 學習筆記二筆記
- ES6 學習筆記三筆記
- ES6的學習筆記筆記
- ES學習筆記(11)--ES6中物件筆記物件
- Redis學習筆記(十一) 伺服器Redis筆記伺服器
- ReactNative學習筆記十一之FlatListReact筆記
- Nginxhttp模組(學習筆記二十一)NginxHTTP筆記
- angular學習筆記(三十一)-$location(1)Angular筆記
- angular學習筆記(三十一)-$location(2)Angular筆記
- Swift學習筆記(二十一)——字典Swift筆記
- 工作學習筆記(十一)Lambda 表示式筆記
- ES6學習筆記--es6簡介筆記
- ES6學習筆記(七)【class】筆記
- ES6學習筆記(八)【class】筆記
- ES6學習筆記(九)【class】筆記
- ES6學習筆記之Function筆記Function
- 前端學習筆記之ES6~~~前端筆記
- JavaScript學習筆記(一) promise和async/waitJavaScript筆記PromiseAI
- oracle學習筆記(十一) 高階查詢Oracle筆記
- Java學習筆記——第十一天Java筆記
- JavaWeb學習筆記——第十一天JavaWeb筆記
- ES6、ES7、ES8特性-學習筆記(一)筆記
- ES2017 —— async await原理AI
- ES6學習筆記(六)【promise,Generator】筆記Promise
- Android OpenGL ES學習筆記之概要Android筆記
- ES6學習筆記3---Symbol筆記Symbol