在ES6之前,JS中主要只有一種函數,ES6之後,加入了其他的一些函數,方便了很多其他場景的處理,尤其是異步場景的處理,用的合適,能大大的簡化異步代碼的處理。
一、普通函數:
這裏所說的普通函數,包含普通函數、函數表達式定義的函數、對象中的方法,箭頭函數等。普通函數是比較常見、常用的,這裏描述一下涉及的調用方式:
// 1.1, 直接函數調用方式:
Person("迪麗熱巴", 18, "直接函數調用");
// 1.2, 方法調用
obj.doSomeThing()
// 2, 構造函數方式
let person = new Person("楊超越", 18, "構造函數方式調用");
// 3, call和applay
Person.call(null, "劉亦菲", 19, "call調用");
Person.apply(null, ["湯唯", 20, "apply調用"]);
// 4, Reflect調用
Reflect.apply(Person, null, ["蔡依林", 20, "Reflect調用"]);
// 5,bind this之後再調用
let fn = Person.bind(null, "楊冪");
fn(18, "bind後調用")
注意:
1,箭頭函數不能當構造函數。
2,對象的簡寫形式的方法不能用作構造函數,會報錯。
const obj = {
// 簡寫形式的方法,不能用作構造函數
Cat(){
this.type = "cat";
},
Dog: function(){
this.name = "dog";
}
}
new obj.Dog();
new obj.Cat();
// 以下是運行結果
new obj.Cat();
^
TypeError: obj.Cat is not a constructor
at Object.<anonymous> (/~~~/object-test1.js:71:1)
at Module._compile (internal/modules/cjs/loader.js:955:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
at Module.load (internal/modules/cjs/loader.js:811:32)
at Function.Module._load (internal/modules/cjs/loader.js:723:14)
at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
at internal/main/run_main_module.js:17:11
二、generator函數
初接觸使用這種函數的時候,感覺理解比較晦澀。看了N遍官方文檔,各種練習之後,大致瞭解了它的使用和運轉方式了。關於generator函數的使用場景,單獨起一片文章介紹,這裏先留個鏈接坑吧: https://blog.csdn.net/yangxinxiang84/article/details/106968137
關於該種類型的函數的詳細介紹,參考 https://es6.ruanyifeng.com/#docs/generator
這裏簡要的描述和彙總下:
function testGenerator(){
console.log(`testGenerator :: enter.`);
let g = generator()
for(let rst of g){
console.log(`testGenerator :: rst = ${rst}`);
}
}
testGenerator();
// generator函數
function* generator2(){
let x = yield 5;
console.log(`generator2 :: x = ${x}`);
let y = yield 6;
console.log(`generator2 :: y = ${y}`);
let z = yield 7;
console.log(`generator2 :: z = ${z}`);
return x + y + z;
}
function testGenerator2(){
console.log(`testGenerator2 :: enter.`);
let g = generator2();
let rst1 = g.next().value;
let rst2 = g.next(100).value; // 將參數替換進入 generator函數 上一個 yield 的返回值 x的地方。
let rst3 = g.next().value;
let rst4 = g.next().value;
console.log(`testGenerator2 :: end, rst1 = ${rst1}, rst2 = ${rst2}, rst3 = ${rst3}, rst4 = ${rst4}`);
}
testGenerator2();
三、async 函數
async函數本質上是generator函數的語法糖,但是使用更清晰和簡單。尤其在處理異步函數的時候,非常方便。
let {log} = require("../../util/logger");
function sleep(ms){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(`sleep end :: ms = ${ms}`)
},ms || 300);
})
}
function mockFetch(url, ms){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
// 模擬resove和reject場景
if(ms % 2 ===0){
resolve(`mockFetch end :: url = ${url}, ms = ${ms}`);
}else{
reject(new Error("mockFetch :: error, not support!!"))
}
},ms || 600);
})
}
async function testNormalAsync(){
log(`testNormalAsync :: enter.`);
// 同步的方式寫異步,但是如果被reject,要寫try catch捕獲
try{
let rst1 = await sleep(1000);
log(`testNormalAsync :: after sleep, rst1 = ${rst1}`);
let rst2 = await mockFetch("baidu.com", 201);
log(`testNormalAsync :: after mockFetch, rst2 = ${rst2}`);
}catch(e){
log(`testNormalAsync :: error, ${e}.`);
}
log(`testNormalAsync :: end.`);
}
testNormalAsync();
// 以下是輸出內容,注意看時間點
[12:12:56:182] testNormalAsync :: enter.
[12:12:57:208] testNormalAsync :: after sleep, rst1 = sleep end :: ms = 1000 //1秒後輸出的
[12:12:57:414] testNormalAsync :: error, Error: mockFetch :: error, not support!!.// 又過了200毫秒輸出的
[12:12:57:414] testNormalAsync :: end.
四、async generator函數
參看:https://blog.csdn.net/yangxinxiang84/article/details/106974312