ES6新特性八:async函數(shù)用法實(shí)例詳解
本文實(shí)例講述了ES6新特性之a(chǎn)sync函數(shù)用法。分享給大家供大家參考,具體如下:
1. async 函數(shù)是什么?
node.js 版本7及之后版本才支持該函數(shù)。
可以簡(jiǎn)單的理解為他是Generator 函數(shù)的語(yǔ)法糖,即Generator 函數(shù)調(diào)用next() 返回的結(jié)果。
① Generator 函數(shù)需要next() 或執(zhí)行器進(jìn)行執(zhí)行,而async 函數(shù)只需和普通函數(shù)一樣執(zhí)行。
② async和await,比起星號(hào)和yield,語(yǔ)義更清楚了。async表示函數(shù)里有異步操作,await表示緊跟在后面的表達(dá)式需要等待結(jié)果,結(jié)果返回才會(huì)向下執(zhí)行。
③ async函數(shù)的返回值是 Promise 對(duì)象,這比 Generator 函數(shù)的返回值是 Iterator 對(duì)象方便多了。你可以用then方法指定下一步的操作。
2. async 函數(shù)與Generator 函數(shù)寫法對(duì)比
var fs = require('fs');
//讀取文件的方法
var readFile = function (fileName) {
return new Promise(function (resolve, reject) {
fs.readFile(fileName, function(error, data) {
if (error) reject(error);
resolve(data);
});
});
};
var gen = function* () {
var f1 = yield readFile('/etc/fstab');
var f2 = yield readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};
var asyncReadFile = async function () {
var f1 = await readFile('/etc/fstab');
var f2 = await readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};
3. async 函數(shù)的作用?
在異步程序中(比如在nodejs),在下一步程序中,需要異步返回的結(jié)果,由于是異步,下一步會(huì)在異步返回前就會(huì)執(zhí)行完,這時(shí)程序就會(huì)出現(xiàn)不是我們預(yù)想的結(jié)果。而async 函數(shù)就可以很好的解決這一問題。我們將異步操作放在await 后面,等待異步返回了結(jié)果程序才會(huì)向下執(zhí)行。
舉例:
/**
* Created by Dason on 2017/3/12.
*/
var mysql = require('mysql');
var pool = mysql.createPool({
host : '127.0.0.1' ,
user : 'root' ,
password : 'root' ,
database : 'dason',
multipleStatements: true
});
//查詢所有id的方法
var getResult = function () {
return new Promise(function(resolve,reject){
pool.getConnection(function(err,connection){
if(err){
console.log(err);
throw err;
}
connection.query('SELECT id FROM user',function(err,result){
if(err){
//console.log(err);
throw err;
//reject(err);
}
console.log(result);
//[{id:1},{id:2},{id:4},{id:5},{id:6},{id:3},{id:7}]
connection.release();
resolve(result);
});
});
});
};
//將所有人的name 改為 A
var updateName = function(id) {
pool.getConnection(function(err,connection){
if(err){
console.log(err);
}
connection.query("update user set name='A' where id = ?",[id],function(err,result){
if(err){
console.log(err);
}
connection.release();
});
});
};
async function update() {
/**
* getResult 是一個(gè)異步函數(shù),放在await 后面,
* 當(dāng)函數(shù)執(zhí)行的時(shí)候,一旦遇到await就會(huì)先返回,
* 等到異步操作完成,將異步結(jié)果返回,再接著執(zhí)行函數(shù)體內(nèi)后面的語(yǔ)句。
*/
var result = await getResult();
console.log("result:"+JSON.stringify(result));
//result:[{"id":1},{"id":2},{"id":4},{"id":5},{"id":6},{"id":3},{"id":7}]
for(const obj of result){
updateName(obj.id);
}
}
update();// async函數(shù)調(diào)用和普通方法一樣
4. 語(yǔ)法
① async 函數(shù)返回一個(gè)promise 對(duì)象。
② async函數(shù)內(nèi)部return語(yǔ)句返回的值,會(huì)成為then方法回調(diào)函數(shù)的參數(shù)。
③ async函數(shù)的await命令后面,可以是Promise 對(duì)象和原始類型的值(數(shù)值、字符串和布爾值,但這時(shí)等同于同步操作),如果不是Promise 對(duì)象,會(huì)被轉(zhuǎn)成一個(gè)立即resolve的 Promise 對(duì)象。
async function f() {
return 'hello world';//會(huì)自動(dòng)調(diào)用Promise.resolve('hello world'),將其轉(zhuǎn)化為promise對(duì)象
}
f().then(v => console.log(v))
// "hello world"
async function f() {
throw new Error('出錯(cuò)了');
}
f().then(
v => console.log(v),
e => console.log(e)
)
// Error: 出錯(cuò)了
④ async函數(shù)返回的 Promise 對(duì)象,必須等到內(nèi)部所有await命令后面的 Promise 對(duì)象執(zhí)行完,才會(huì)發(fā)生狀態(tài)改變,除非遇到return語(yǔ)句或者拋出錯(cuò)誤。也就是說,只有async函數(shù)內(nèi)部的異步操作執(zhí)行完,才會(huì)執(zhí)行then方法指定的回調(diào)函數(shù)。
注意1:await命令后面的Promise對(duì)象,運(yùn)行結(jié)果可能是rejected,所以最好把a(bǔ)wait命令放在try...catch代碼塊中。
async function main() {
try {
var val1 = await firstStep();
var val2 = await secondStep(val1);
var val3 = await thirdStep(val1, val2);
console.log('Final: ', val3);
}
catch (err) {
console.error(err);
}
}
⑤ await命令后面的 Promise 對(duì)象如果變?yōu)?code>reject狀態(tài),則reject的參數(shù)會(huì)被catch方法的回調(diào)函數(shù)接收到。
async function f() {
await Promise.reject('出錯(cuò)了');//沒有return,即不是async函數(shù)返回的promise對(duì)象,也會(huì)被catch方法的回調(diào)函數(shù)接收到
}
f()
.then(v => console.log(v))
.catch(e => console.log(e))
// 出錯(cuò)了
注意2:多個(gè)await命令后面的異步操作,如果不存在繼發(fā)關(guān)系,最好讓它們同時(shí)觸發(fā)。不然會(huì)增加耗時(shí)。
//耗時(shí)寫法 let foo = await getFoo(); let bar = await getBar(); //同時(shí)觸發(fā) // 寫法一 let [foo, bar] = await Promise.all([getFoo(), getBar()]); // 寫法二 let fooPromise = getFoo(); let barPromise = getBar(); let foo = await fooPromise; let bar = await barPromise;
希望本文所述對(duì)大家ECMAScript程序設(shè)計(jì)有所幫助。
- ES6中非常實(shí)用的新特性介紹
- JavaScript ES6的新特性使用新方法定義Class
- JavaScript中的Reflect對(duì)象詳解(ES6新特性)
- 深入淺出ES6新特性之函數(shù)默認(rèn)參數(shù)和箭頭函數(shù)
- 簡(jiǎn)單談?wù)凟S6的六個(gè)小特性
- ES6新特性之Symbol類型用法分析
- ES6(ECMAScript 6)新特性之模板字符串用法分析
- ES6新特性之變量和字符串用法示例
- ES6新特性之模塊Module用法詳解
- ES6新特性之字符串的擴(kuò)展實(shí)例分析
- ES6新特性二:Iterator(遍歷器)和for-of循環(huán)詳解
- ES6新特性六:promise對(duì)象實(shí)例詳解
- ES6新特性七:數(shù)組的擴(kuò)充詳解
- ES6新特性之類(Class)和繼承(Extends)相關(guān)概念與用法分析
- 讓微信小程序支持ES6中Promise特性的方法詳解
- ES6新特性:使用export和import實(shí)現(xiàn)模塊化詳解
- es6新特性之 class 基本用法解析
- ES6 13個(gè)新特性總結(jié)
相關(guān)文章
WebStorm中如何將自己的代碼上傳到github示例詳解
這篇文章主要介紹了WebStorm中如何將自己的代碼上傳到github,本文分步驟通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
使用formatter函數(shù)設(shè)置Echarts的tooltip中動(dòng)態(tài)單位
這篇文章主要為大家介紹了使用formatter函數(shù)設(shè)置Echarts的tooltip中動(dòng)態(tài)單位實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
將HTML的左右尖括號(hào)等轉(zhuǎn)義成實(shí)體形式的兩種實(shí)現(xiàn)方式
這篇文章主要介紹了將HTML的左右尖括號(hào)等轉(zhuǎn)義成實(shí)體形式的兩種實(shí)現(xiàn)方式,需要的朋友可以參考下2014-05-05
動(dòng)態(tài)讀取JSON解析鍵值對(duì)的方法
這篇文章主要介紹了動(dòng)態(tài)讀取JSON解析鍵值對(duì)的方法,需要的朋友可以參考下2014-06-06
JS實(shí)現(xiàn)分頁(yè)導(dǎo)航效果
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)動(dòng)態(tài)頁(yè)碼及分頁(yè)導(dǎo)航,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02

