ES2017 中的非同步函式詳解(async function)
阿新 • • 發佈:2019-01-24
非同步函式中有兩個新的關鍵字async
和await
async
就是非同步的意思
await
就是等的意思. 暫停函式的執行, 等待非同步任務完成.
宣告非同步函式
/*使用關鍵字 async 宣告非同步函式. 引數宣告和普通函式沒有任何的區別*/
async function testAsync(a, b){
console.log(a, b);
return "非同步";
}
/*呼叫非同步函式, 返回值是一個 Promise 物件*/
var promise = testAsync(10, 20);
console.log(promise);
說明:
使用關鍵字
async
非同步函式預設返回一個已決的
promise
.也可以在非同步函式中新增
return "abc"
語句, 則會把這個值封裝成Promise.resolve("abc")
如果想返回一個
reject
的Promise
則可以在函式內部丟擲一個異常即可.
await
如果非同步函式內沒有出現await
則上面的非同步函式和一個普通的函式沒有太大的區別.
如果有了await
則會大大的不一樣.
await
是等待的意思, 到底在等啥?
在等待一個非同步任務的完成. 一般是等待一個 Promise resolve. 當然可以等任何其他的值.
function resolve2Second (x){
return new Promise(function (resolve, reject){
setTimeout(() => resolve(x), 2000);
})
}
async function add(){
var a = await resolve2Second(20); // 2 秒鐘之後 a為 20
var b = await resolve2Second(30); // 2 秒鐘之後 b為30
return a + b; //
}
add().then(function (value){ // 4s中之後, 返回的promsie 會變成已決狀態, 執行then中的函式
console.log(value); // 50
})
說明:
await
會等待, 等到Promise resolve
之後, 他的運算的最終結果是resolve(值)
中的值.有一點需要注意的時候,
await
只能在非同步函式內執行.- 呼叫
async
函式雖然有等待, 但是並不會導致阻塞, 因為他內部的所有阻塞都封裝在Promise
物件中非同步執行.
非同步函式的優勢在哪裡
需求:
考慮有多個任務, 每個任務都依賴上一個任務的結果. 用setTimeout
來模擬每個任何的耗時.
使用單純的Promise
來完成
/*n表示耗時, n+1000傳給下個任務*/
function doSomething(n){
return new Promise((resolve, reject) =>{
setTimeout(() => resolve(n + 1000), n)
})
}
function task1(n){
console.log("任務1:" + n)
return doSomething(n);
}
function task2(n){
console.log("任務2:" + n)
return doSomething(n);
}
function task3(n){
console.log("任務3:" + n)
return doSomething(n);
}
function doit(){
task1(1000)
.then(function (time2){
return task2(time2);
})
.then(function (time3){
return task3(time3);
})
.finally(function (){
console.log("任務結束");
})
}
doit();
使用 async
和await
如果使用非同步函式配合await
會發現程式碼像同步一樣舒服.
/*n表示耗時, n+1000傳給下個任務*/
function doSomething(n){
return new Promise((resolve, reject) =>{
setTimeout(() => resolve(n + 1000), n)
})
}
function task1(n){
console.log("任務1:" + n)
return doSomething(n);
}
function task2(n){
console.log("任務2:" + n)
return doSomething(n);
}
function task3(n){
console.log("任務3:" + n)
return doSomething(n);
}
async function doit(){
var time2 = await task1(1000) // 等待第一個任務 resolve
var time3 = await task2(time2) // 等待第二個任務 resolve
var result = await task3(time3)
console.log("任務結束:" + result);
}
doit();