0%

如何解決非同步? 回呼函式 Callbacks、Promises 物件、Async/Await 非同步流程控制

常見的非同步

setTimeoutXMLHttpRequest
這裡以 setTimeout 做示範:點擊按鈕,會兩數相加,兩秒後顯示結果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let btn =document.querySelector('#btn');

// 監聽
btn.addEventListener('click',test)

// 非同步的程式
function delayAdd(n1,n2,sec) {
setTimeout(function name(params) {
return n1 + n2
},sec)
}
function test(params) {
let result=delayAdd(1,2,2000)
console.log(result)
}

解決方式

回呼函式 Callbacks

1
2
3
4
5
6
7
8
9
10
function delayAdd(n1,n2,sec,callback) {
setTimeout(function (params) {
callback(n1 + n2)
},sec)
}
function test(params) {
delayAdd(1,2,2000,function (result) {
console.log(result)
})
}

Promise

  • 創建 new Promise
  • reslove 對應 than
  • reject 對應 cath
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function delayAdd(n1,n2,sec) {
    return new Promise(function (reslove,reject) {
    setTimeout(function (params) {
    reslove(n1 + n2)
    },sec)
    })
    }
    function test(){
    let promise=delayAdd(1,2,2000)
    promise.then(function (result) {
    console.log(result)
    })
    }

    Promise.all

    1
    2
    3
    4
    5
    6
    7
    function test(params) {
    let promise1=delayAdd(1,2,2000)
    let promise2=delayAdd(3,4,3000)
    Promise.all([promise1,promise2]).then(function (results) {
    console.log(results)
    })
    }

    Async/Await

    本質還是 Promise,簡化 Promise 的語法糖。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function delayAdd(n1,n2,sec) {
    return new Promise(function (reslove,reject) {
    setTimeout(function (params) {
    reslove(n1 + n2)
    },sec)
    })
    }
    async function test(params) {
    let result=await delayAdd(1,2,2000)
    console.log(result)
    }

    範例

    本文範例程式碼
    XMLHttpRequest + Promise 範例

    參考文章

    https://www.youtube.com/watch?v=NOprCnnjHm0