changed 3 years ago
Linked with GitHub

Async JS Crash Course

tags: Javascript

使用範例來理解Async JS在什麼情況下適合作用:

  • 取得post貼上DOM延遲一秒鐘
  • 創造新的post花了兩秒鐘

這樣會發生什麼情況?

DOM會先PO post上去不等新的post創造好,所以永遠更新不到新的post

const posts = [{ title: 'Post One', body: 'This is post one' }, { title: 'Post Two', body: 'This is post two' }, ]; // 把取得的post貼到DOM上面 延遲一秒鐘 function getPost() { setTimeout(() => { let output = ''; posts.forEach((post, index) => { output += `<li>${post.title}</li>`; }); document.body.innerHTML = output; }, 1000); } //創造一個新的post丟上去花了兩秒鐘 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不需要加上()要特別留意

//創造一個新的post丟上去花了兩秒鐘 //這邊的callback就代表了getPosts所以必須等創造好了新的post之後 // getPost才會觸發也才會把取的的物件推上去DOM所以就可以顯示新的post搂! 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方法抓取錯誤的內容

function createPost(post, ) { //如果promise解決會呼叫resolve //如果promise錯誤則呼叫reject return new Promise((resolve, reject) => { setTimeout(() => { posts.push(post); // 解釋promise內部的兩個參數的判斷是如何運作 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就好瞜!

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的階段被真正抓取到資料

//使用兩個.then因為要轉換JSON格式 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去執行這樣就會顯示摟!

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處理完成後,才會往getPosts去執行 async function init() { await createPost({ title: 'Post Three', body: 'This is post three' }); getPosts(); } init();

示範fetch API 相關的async寫法

不用.then一切都更乾淨好讀

一樣fetch都需要資料轉換,但是這邊重新指派一個變數處理比較特別

async function fetchUsers() { const res = await fetch('https://jsonplaceholder.typicode.com/users'); const data = await res.json(); console.log(data); } fetchUsers();

fetch的資料印出:

Select a repo