JavaScript中的函數分類和講解:普通函數(含對象的方法)、generator函數、async函數、async generator函數使用講解

在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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章