javascript核心篇 - Promise

javascript核心篇 - Promise

最近在上六角學院的js核心篇,將筆記整理出來跟大家分享。

Promise

用來處理非同步行為(Ajax)。

axios

寫法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
function promiseFn (num) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(num) {
resolve('success!!')
} else {
reject(new Error('fail!!!'))
}
}, 0)
})
}

promiseFn(1)
.then((res) => {
console.log(res);
})
//捕捉失敗訊息
.catch((err) => {
console.error(err);
})

```

### 鍊結
一個完成後在做下一個
```javascript
function promiseFn (num) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(num) {
resolve(`成功 值為${num}`)
} else {
reject(new Error('fail!!!'))
}
}, 0)
})
}

promiseFn(1)
.then((res) => {
console.log(res);
//第二次非同步
return promiseFn(2);
})
//第二次非同步完成的結果
.then(res => {
console.log(res);
return promiseFn(3);
})
.then(res => {
console.log(res);
return promiseFn(3);
})
//捕捉失敗訊息
.catch((err) => {
console.error(err);
})
//新的鏈結
.then(res => {
console.log(res);
return promiseFn(4);
})

promise的鍊結要注意,若是其中一環拋出錯誤,後面皆不會執行,直接跳catch,catch之後的promise會形成新的鏈結

then可以傳入兩個callback, 一個接成功一個接失敗

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function promiseFn (num) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(num) {
resolve(`成功 值為${num}`)
} else {
reject(new Error('fail!!!'))
}
}, 0)
})
}

promiseFn(1)
.then((res) => {
console.log('success')
return new promiseFn(2)
}, (reject) => {
console.log('fail')
return new promiseFn(3)
})
.then((res) => {
console.log('success' + res)
}, (reject) => {
console.log('fail')
})

技巧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function promiseFn(num, time = 500) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(num) {
resolve('success!!!' + num)
} else {
reject('fail!!!');
}
}, time);
})
}

promiseFn(1, 2000)
.then(res => {
console.log(res);
})

Promise.all([arr])

使用promise.all()可以同時發送多個請求,等到全部都完成後再進行下一步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 全部成功
Promise.all([
promiseFn(1, 100),
promiseFn(2, 300),
promiseFn(3, 500)
]).then((res) => {
console.log(res); //["success!!!", "success!!!", "success!!!"]
})

//其中一項失敗
Promise.all([
promiseFn(1, 100),
promiseFn(false, 300),
promiseFn(3, 500)
])
.then((res) => {
console.log(res);
})
.catch((rej) => {
console.log(rej)
})
//error: fail!!!

全部完成後會以陣列回傳所有結果,但鍊接中若有其中一項失敗,則全部失敗

Promise.race([arr])

只回傳最快得到結果的,只傳一個,根據最快完成的promise結果決定成功或失敗

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 全部成功
Promise.race([
promiseFn(1, 500),
promiseFn(2, 300), //最快的
promiseFn(3, 500)
]).then((res) => {
console.log(res); // success!!!2
})

//其中一項失敗 (失敗為最快的)
Promise.race([
promiseFn(1, 700),
promiseFn(false, 300),
promiseFn(3, 500)
])
.then((res) => {
console.log(res);
})
.catch((rej) => {
console.log(rej)
})
//error: fail!!!

promise + ajax

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

var url= 'https://jsonplaceholder.typicode.com/todos/1';

var req = new XMLHttpRequest();

req.open('GET', url);

//資料取得完成後進行
req.onload = function () {
if (req.status === 200) {
console.log(req.response);
} else {
return new Error('fail!!!')
}
};
/*{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}

*/

promise改寫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var url= 'https://jsonplaceholder.typicode.com/todos/1';

function get(url) {
return new Promise((resolve, reject) => {
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function () {
if (req.status === 200) {
resolve(req.response);
} else {
reject(req);
}
};
req.send();
});
};

//串聯
get(url)
.then((res) => {
console.log('got!!', res);
return get(url)
})
.then((res) => {
console.log('got twice!!!',res)
})
.catch((rej) => new Error(rej))
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×