了解非同步.同步控制

2020-04-29
JavaScript

了解非同步.同步控制(asynchronous)

- Callback 回呼函式

- Promise 物件

- Async/Await 語法


以下為正常function使用

1
2
3
4
5
6
7
8
function add (n1, n2) {
return n1+ n2;
}
function test() {
let result = add(3, 4);
console.log(result); // 會顯示7
}
test()

這邊為非同步的程式(setTimeout,AJAX,網路連線等都為非同步):

1
2
3
4
5
6
7
8
9
10
11
12
13
function delayedAdd(n1, n2, delayTime) {
//在這,程式會直接往下繼續跑,不會等延遲,所以result拿到undefined
window.setTimeout(function() {
return n1+ n2;
// 這裡的returnreturn setTimeout這個function,所以顯示undefined
}, delayTime);
}
function test() {
let result = delayedAdd(3, 4, 2000);
console.log(result); // undefined
// 因為非同步,所以不會等他跑完延遲,直接繼續其他動作
}
test();

解決非同步方法:

  • Callback 回呼函式 : 當這個事件被觸發,就會去執行callback函式也就是說他要滿足函式內的某些條件才會去執行callback函式
    以下為範例:

    function delayedAdd(n1, n2, delayTime, callback) { //callback放在function第四個參數
    window.setTimeout(function() {
     callback (n1+ n2);
    }, delayTime);
    }
    function test() {
     delayedAdd(3, 4, 2000, function callback(result) {
     console.log(result); //延遲2秒後顯示7
    });
    }
    test();
  • Promise 物件 : 建立 Promise 物件: new Promise(執行函式)
    以下為範例:

    function delayedAdd(n1, n2, delayTime) { //建立 Promise 物件: new Promise(執行函式)
     return new Promise(function (resolve, reject) {
       window.setTimeout(function() {
         resolve(n1+n2); 
         reject('壞了', '!!');
       }, delayTime);  //工作完成,呼叫resolve函式,並把結果透過參數傳遞
     });
    }
    function test() {
     let promise = delayedAdd(3, 4, 5000);
     promise.then((result) => { // 成功
       console.log(result);    // 延遲完resolve後用then去取出resolve後的資料
       }).catch((error) => { // reject回傳這個,未成功
       console.log('Error',error)
     });
    }
    test();

    另外,還可以一次運行多個Promise,但要先多個Promise都完成後,才會繼續動作
    以下為範例:

    function delayedAdd(n1, n2, delayTime) { //建立 Promise 物件: new Promise(執行函式)
    return new Promise(function (resolve, reject) {
     window.setTimeout(function() {
       resolve(n1+n2); //工作完成,呼叫resolve函式,並把結果透過參數傳遞
     }, delayTime);
    });
    }
    function test() {
     let promise1 = delayedAdd(3, 6, 2000);
    let promise2 = delayedAdd(2, 5, 3000);
    // 多個工作完成,才繼續工作,不過這邊他是同時進行動作,所以總共讀秒是3秒
    Promise.all([promise1, promise2]).then(function (results) {
     console.log(results);
    })
    }
    test();
  • Async/Await (簡化 Promise語法) : 邏輯與 Promise類同,必須要有一個函式return物件
    以下為範例:
    function delayedAdd(n1, n2, delayTime) {
     //建立 Promise 物件: new Promise(執行函式)
     return new Promise(function (resolve, reject) {
       window.setTimeout(function() {
       resolve(n1+n2);   
       //工作完成,呼叫resolve函式,並把結果透過參數傳遞
       }, delayTime);
     });
    }
    async function test() { //函式前加上async開頭
     let result = await delayedAdd(3, 4, 2000);
     // 這裡的result會直接從resolve傳遞進資料,await會等待resolve回來
     console.log(result); // 7
    }
    test();



寫起來記錄一下

參考 :


Comments: