bonus: es8 async& await - github pagesajax, the async/await style 9. outline •es6 promises...

17
Bonus: ES8 Async & Await Shan-Hung Wu & DataLab CS, NTHU

Upload: others

Post on 02-Oct-2020

11 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

Bonus: ES8 Async & Await

Shan-Hung Wu & DataLabCS, NTHU

Page 2: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

Outline• ES6 Promises• ES8 Async & Await• Pitfalls

2

Page 3: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

ES6 Promise• A value available

in the future• Separation of

concerns– Handlers can be

written in different places

• Use arrow funcfor this

3

// in method1()const p = new Promise((resolve, reject) => {... // do asynchronous job hereif (success) resolve(data);else reject(err);

});return p;

// in method2(p)const p2 = p.then(data => {

... // process datareturn data2

}); // always returns a new Promisereturn p2;

// in method3(p2)p2.then(data2 => {... process data2

}).catch(err => {... // handle err

}); // always returns a new Promise

Page 4: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

Execution Flow

• Chain then and/or catch as long as you like

• Reject mode: – throw new Error()

• Resolve mode:– return

4

resolve() reject()

return throw

return throw

Page 5: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

Axios and AJAX Requests

• Requests can be canceled5

const axios = require('axios’);

// GET requestaxios.get('...url...').then(res => {res.status // HTTP response code (e.g., 200, 401)res.data // object parsed from HTTP response bodyres.headers // HTTP presonse headers

}).catch(err => {console.log(err.response.status);

});

// POST requestaxios.post('...url...', {... // request body

}).then(...).catch(...);

Page 6: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

Outline• ES6 Promises• ES8 Async & Await• Pitfalls

6

Page 7: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

ES8 Async & Await

• Goal: to make asynchronous code looks more consistent with synchronous code

• Now, supported by major browsers and Node.JS v7.6+

7

Page 8: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

Example

8

// ES6 Promisefunction getFirstUser() {return getUsers().then(users => users[0].name)

.catch(err => ({name: 'default user'

}));}

// ES7 Async/Awaitasync function getFirstUser() {try {// line blocked until promise // resolved/rejected.let users = await getUsers();return users[0].name;

} catch (err) {return {name: 'default user'

};}

}

• An async functionreturns a promise

• Await on a promise until value available

• Try/catch for resolve/reject

Page 9: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

const axios = require('axios’);

async function getFirstUser() {try {let users = await axios.get('...url...');return users[0].name;

} catch (err) {console.log(err.response.status);return {name: 'default user'

};}

}

AJAX, the Async/Await Style

9

Page 10: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

Outline• ES6 Promises• ES8 Async & Await• Pitfalls

10

Page 11: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

Pitfall #1: Mixing Callbacks/Promises

• Choose one style, and stay consistent in your entire project– Callbacks– ES6 Promise– ES8 Async/await

• Increases readability of your code

11

Page 12: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

Pitfall #2: await Not in asyncFunction

• You can use await at top level• But when using await is in a function, the

function must be async

12

await axios.get('...url...’); // OK

function getUser(id) {return await axios.get('...url...’); // error

}

async function getUser(id) {return await axios.get('...url...’); // OK

}

Page 13: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

const axios = require('axios’);

async function getUsers(ids) {let users = [];try {ids.forEach(async id => {let user = await axios.get('...url...’);users.push(user);

});} catch (err) {...}return users;

}const vips = await getUsers(...);

Pitfall #3: Array.forEach()

• Empty usersreturned immediately– Elements added later

13

Page 14: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

Solution: Use for Instead

14

const axios = require('axios’);

async function getUsers(ids) {let users = [];try {for (let id of ids) {let user = await axios.get('...url...’);users.push(user);

}} catch (err) {...}return users;

}const vips = await getUsers(...);

Page 15: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

Pitfall #4: Reduced Parallelism

• If order doesn’tmatter, why get user sequentially?

15

const axios = require('axios’);

async function getUsers(ids) {let users = [];try {for (let id of ids) {let user = await axios.get('...url...’);users.push(user);

}} catch (err) {...}return users;

}const vips = await getUsers(...);

Page 16: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

16

// get a user object; blockedlet fu = await getFirstUser();

// get a promise immediately; async jobs startslet fp = getFirstUser();

// sequential awaitinglet fu = await getFirstUser();let lu = await getLastUser();

// parallel awaitinglet fp = getFirstUser(); // async jobs startslet lp = getLastUser(); // async jobs startslet [fu, lu] = await Promise.all([fp, lp]);

• Promise.all() creates a promise that resolves only when all child promises resolve

Parallel Awaiting

Page 17: Bonus: ES8 Async& Await - GitHub PagesAJAX, the Async/Await Style 9. Outline •ES6 Promises •ES8 Async& Await •Pitfalls 10. Pitfall #1: Mixing Callbacks/Promises •Choose one

Solution

17

const axios = require('axios’);

async function getUsers(ids) {let promises = [];try {for (let id of ids) {let promise = axios.get('...url...’);promises.push(promise);

}} catch (err) {...}return await Promise.all(promises);;

}const vips = await getUsers(...);