主題

輕鬆無痛讓js同步

深海異音 | 2020-04-30 08:04:08 | 巴幣 196 | 人氣 2731

JavaScript非同步的函數非常多,像是:ajax請求、圖片處理、nodejs的資料庫存取 等..
一定有很多剛入門JS人,被非同步的概念折騰的不要不要
偏偏網路上找的教學,一篇比一篇完整(複雜)

所以這邊我就不結解釋async跟Promise的用法了,直接說明如何解決問題,讓程式碼真真正正的「由上而下執行」



在電腦的瀏覽器按F12開啟「DevTools」就能測試下面的程式碼


用很常見的 setTimeout (延遲執行)來說明
如果非同步的函數下面還有程式碼,那麼程式碼就不會是「由上而下執行」
var a = 0;
setTimeout(function () {
    a = 999; // 1秒過後才會執行這裡
}, 1000);
console.log(a); // 印出0


這時候只需要一個東東就能解決
//在這個區塊裡面的程式碼會一直等待
await new Promise((resolve, reject) => {
    resolve(); // 呼叫這個函數後,才會繼續往下執行
})


只需要用上面的東東把非同步的程式碼包住,程式碼就非常乖的由上而下執行
var a = 0;
await new Promise((resolve, reject) => {//進入等待
    setTimeout(function () {
        a = 999;
        resolve();//繼續往下執行
    }, 1000);
})
console.log(a); //印出999


把這東西用在迴圈裡面也完全沒問題
for (let i = 1; i <= 10; i++) {
    await new Promise((resolve, reject) => {//進入等待
        setTimeout(function () {
            resolve();//繼續往下執行
        }, 1000);
    })
    console.log(i + '秒過去了');
}
console.log('全都結束了');



這邊有個點要注意
如果要在函數裡面使用這個語法,則必須在function前面加上「async」
呼叫這個函數的地方要在前面加上「await」
//需要等待非同步的函數,前面要加「async」
async function dd() {
    var a = 0;
    await new Promise((resolve, reject) => {
        setTimeout(function () {
            a = 999;
            resolve();//繼續往下執行
        }, 3000);
    })
    return a;
}

//呼叫需要等待的非同步函數,前面要加「await」
var d = await dd();
console.log(d);//印出999




(下面的程式碼不能直接執行)


最後用請求多個json來示範

假設有一個函數需要傳入3個json才能執行
要取得這3個json,需要對另外三個網址請求資料
如果用上面教的方法來處理,那麼只要宣告好函數,就能輕鬆愉悅的用4行程式碼來解決

var json_A = await get_json('/get_A.json');
var json_B = await get_json('/get_B.json');
var json_C = await get_json('/get_C.json');
需要傳入3個json才能執行的函數(json_A, json_B, json_C);

/**
*
*/
async function get_json(u) {

    let json = '';

    await new Promise((resolve, reject) => {
        $.ajax({
            url: u,
            type: "get",
            success: function (s) {
                json = s;
                resolve();//繼續往下執行
            },
            error: function (xhr, ajaxOptions, thrownError) {
                resolve();//繼續往下執行
            }
        });
    })

    return json;
}



如果用傳統的寫法就會像這樣
可讀性0分、完全不可維護




都看到這了,不貼個JS也說不過去



送禮物贊助創作者 !
0
留言

創作回應

あかつき
剛好需要這個 謝謝異音大
2020-04-30 10:27:04
Centon
之前寫機器人蠻常用到的
請求api要等資料回傳才能發送訊息
剛開始不知道的時候一直回傳空資料還蠻頭痛的
2020-04-30 10:43:11
飄飄小宅
才華洋溢,雖然看不懂,不過先給讚。
2020-04-30 11:34:10
♙♲⚙\~O_O~/⚙♲♙
才華洋溢
2020-04-30 11:38:57
一邊寫程式一邊貼JS是良好的學習態度[e19]
2020-04-30 13:54:54

更多創作