創作內容

90 GP

輕鬆無痛讓js同步

作者:深海異音│2020-04-30 08:04:08│巴幣:196│人氣:2636
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也說不過去



引用網址:https://home.gamer.com.tw/TrackBack.php?sn=4766159
All rights reserved. 版權所有,保留一切權利

相關創作

留言共 16 篇留言

乃乃
我只是看到JS就進來了

04-30 08:09

你再繼續唬爛啊
才華洋溢

04-30 08:11

卡斯托拉提夫
$. ajax是jquery的寫法吧......

04-30 08:25

深海異音
是jQuery沒錯,怕用新的語法會讓沒看過的人看不懂04-30 08:43
迷茫小呈
才華洋溢

04-30 08:35

fairylag
先按個讚,以免別人以為我不懂

04-30 08:43


才華洋溢,先按讚,10年後再看。活到現在目前程式語言0基礎

04-30 08:45

月下吹雪
超愛這個畫師

04-30 08:46

Fuhzer
才華洋溢...

04-30 09:14

白色爛狐
印象中jquery的ajax本來就會return promise
應該可以直接await $.ajax()

04-30 09:30

ねいねい
才華洋溢

04-30 09:59

烤肉必焦
每次點進來都有不同的JS???
異音同學的頁面觸及要被我點爆ㄌ

04-30 10:13

あかつき
剛好需要這個 謝謝異音大

04-30 10:27

Centon
之前寫機器人蠻常用到的
請求api要等資料回傳才能發送訊息
剛開始不知道的時候一直回傳空資料還蠻頭痛的

04-30 10:43

飄飄小宅
才華洋溢,雖然看不懂,不過先給讚。

04-30 11:34

♙♲⚙\~O_O~/⚙♲♙
才華洋溢

04-30 11:38


一邊寫程式一邊貼JS是良好的學習態度[e19]

04-30 13:54

我要留言提醒:您尚未登入,請先登入再留言

90喜歡★hbl917070 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:用更人性化的方式操作Go... 後一篇:Mouse2Touch ...

追蹤私訊切換新版閱覽

作品資料夾

john441剛好看到的你
寫好TGS2022逛完的感想 跟 之後的行程 歡迎看看^^看更多我要大聲說昨天23:48


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】