Async JS Crash Course
使用範例來理解Async JS在什麼情況下適合作用:
- 取得post貼上DOM延遲一秒鐘
- 創造新的post花了兩秒鐘
這樣會發生什麼情況?
DOM會先PO post上去不等新的post創造好,所以永遠更新不到新的post
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
| const posts = [{ title: 'Post One', body: 'This is post one' }, { title: 'Post Two', body: 'This is post two' }, ];
function getPost() { setTimeout(() => { let output = ''; posts.forEach((post, index) => { output += `<li>${post.title}</li>`; }); document.body.innerHTML = output; }, 1000); }
function createPost(post) { setTimeout(() => { posts.push(post); }, 2000); }
getPost();
createPost({ title: 'Post Three', body: 'This is post Three' });
|
使用callback:
使用callback代表getPosts,這樣一來就會在創造好新的post之後才會觸發getPosts整個過程會在兩秒內完成
需要注意callback的寫法在呼叫函式的部分撰寫的callback不需要加上()要特別留意
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
function createPost(post, callback) { setTimeout(() => { posts.push(post); callback(); }, 2000); }
createPost({ title: 'Post Three', body: 'This is post Three' }, getPosts)
|
使用promise:
- promise解決會呼叫resolve
- promise錯誤則呼叫reject
promise成功則會使用then()內部的函式順利的印出新的post
promise失敗(改寫error變數成true)則會顯示錯誤訊息在console裡面
也可以使用catch
方法抓取錯誤的內容
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 createPost(post, ) {
return new Promise((resolve, reject) => { setTimeout(() => { posts.push(post);
const error = false;
if (!error) { resolve(); } else { reject('Error: something went wrong'); }
}, 2000); }); }
createPost({ title: 'Post Three', body: 'This is post three' }).then(getPosts).catch(err => console.log(err));
|
示範promise.all
常常promise會不只一個,一個一個接then太累了,所以可以使用promise.all一次抓住一同使用.then就好瞜!
1 2 3 4 5
| const promise1 = Promise.resolve('hello world'); const promise2 = 10; const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 2000, 'Goodbye'));
Promise.all([promise1, promise2, promise3]).then(values => console.log(values));
|
最後.then的印出結果
示範fetch API 相關的promise寫法
使用fetch抓取資料的話必須轉化格式所以在指派給變數的階段就要先.then轉換格式
這樣才可以在promise.all的階段被真正抓取到資料
1 2 3 4
| const promise4 = fetch('https://jsonplaceholder.typicode.com/users').then(res => res.json());
Promise.all([promise1, promise2, promise3, promise4]).then(values => console.log(values));
|
最後.then的印出結果
使用async:
await
等待一個同步的過程或動作去完成後才去執行其他動作
等待createPost處理完內部的函式createPost後也就是創造新的post後,才會往getPosts去執行這樣就會顯示摟!
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
| function createPost(post, ) { return new Promise((resolve, reject) => { setTimeout(() => { posts.push(post);
const error = false;
if (!error) { resolve(); } else { reject('Error: something went wrong'); }
}, 2000); }); }
async function init() { await createPost({ title: 'Post Three', body: 'This is post three' });
getPosts(); }
init();
|
示範fetch API 相關的async寫法
不只用.then一切都更乾淨好讀
一樣fetch都需要資料轉換,但是這邊從新指派一個變數處理比較特別
1 2 3 4 5 6 7 8
| async function fetchUsers() { const res = await fetch('https://jsonplaceholder.typicode.com/users'); const data = await res.json();
console.log(data); }
fetchUsers();
|
fetch的資料印出: