---
# System prepended metadata

title: Promise非同步觀念
tags: [Promise, javascript]

---

# Promise非同步觀念
以下有一段程式碼，先來猜一下他們的執行順序為何？
```javascript=
function getData(){
    setTimeout(()=>{
        console.log(’...已取得遠端資料‘)
    },0)

}

cost component ={
    init(){
         console.log(1);
         getData();
         console.log(2);
    }

}

component.init();

```
getData()裡面包了一個setTimeout，程式碼執行的順序是由上至下的，但是非同步的行為一定會在最下面，因此上面這段程式執行的順序，會是:

```javascript=
1
2
...已取得遠端資料
```
基本上只要看到非同步行為，順序就把它放在最後面。



---
### Promise使用方法

Promise要解決的問題，是為了解決傳統非同步語法難以建構及管理的問題(call back Hell)。

先來了解一下怎麼使用：

```javascript=
const promiseSetTime = (status)=>{

    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            if(status){
                resolve('promiseSetTime成功')
            }else{
                reject('promiseSetTime失敗')
            }
        },0);    
    });
}
```

上面的function是為了要檢視promise的運行方式，所以會先帶一個status參數，依照傳進來的status來決定執行的成功或失敗，但實際的程式並不會這樣寫，要特別注意。

Promise 建構函式建立同時，必須傳入一個函式作為參數（executor function），此函式的參數包含 resolve, reject，這兩個方法分別代表成功與失敗的回傳結果，特別注意這兩個僅能回傳其中之一，**回傳後表示此 Promise 事件結束。**

Promis執行的時候，會先讓所以同步的程式先執行完畢，並且等待非同步的程式執行完之後，依據執行的結果跑resolve或reject。


```javascript=
先來執行一次成功的：
promiseSetTime(true)
.then(function(res){
    console.log(res)
})

/// promiseSetTime成功
```

### Promise的串接功能
如果需要有順序的call API，比如第一個call完再接著第二個、第三個的時候，就會需要串接的功能。

```javascript=
promiseSetTime(true)
.then(function(res){
    console.log(1,res)
    // 帶入下一個非同步行為
    return promiseSetTime(true);
})
.then(res=>{
    console.log(2,res)
});
```

照這樣的寫法就會依序執行

###  失敗捕捉
如果失敗會用reject回傳，catch做接收
```javascript=
promiseSetTime(flase)
.then(res=>{
    console.log(res);
    // 這邊會出現失敗    
})
.catch(err=>{
    console.log(err);
});

// promiseSetTime失敗
```

### 元件運用
``` javascript
const component ={
    data:{},
    init(){
        console.log(this);
        promiseSetTime(true)
        .then(res => {
            this.data.res = res;
            console.log(this.data)
        });
    }
}

component.init();
```

第一個`console.log(this)`回傳的會是這個物件本身`{data:{},init:f}`
第二個`console.log(this.data)`回傳的會是`res:promiseSetTime成功`

以上這個方法是比較常在實際上運用的方法，會把Ajax的資料寫回data去做使用，也跟`Vue`的data與methods很像！

###### tags: `javascript` `Promise`