- Notifications
You must be signed in to change notification settings - Fork0
toniov/es6-promises-workshop
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Valverde Antonio
- Why Promises?
- What is a Promise?
- Promise standard
- Producing a Promise
- Consuming a Promise
- Instance methods
- then()
- catch()
- Static methods
- Promise.all()
- Promise.race()
- Promise.resolve()
- Promise.reject()
- Promise limitations
- Compatibility Promises/callbacks in libraries
- Quizes
- References
- Chaining is simpler
- Promise-based functions return results, they don’t continue execution via callbacks
- The caller stays in control
- Cleaner signatures
- With callbacks, the parameters of a function are mixed. With Promises all parameters are input
- Standardized
- Before promises: Node.js callbacks, XMLHttpRequest, IndexedDB, etc
- Call the callback more than once
- Call the callback too early
- Don’t call the callback
- Errors could create a synchronous reaction whereas nonerrors would be asynchronous
This makes callbacks not very trustable in some cases.
→ Promises are resolved only once by definition
→ The callback you provide to Promise instances then(..) method will always be called asynchronously
→ A timeout can be set using Promise.race(..)
→ Promises turn even JS exceptions (synchronous) into asynchronous behavior
Before the result is ready, the Promise is
pendingIf a result is available, the Promise is
fulfilledIf an error happened, the Promise is
rejected
From now on I will speak about ES6 Native promises.
bluebirdhttps://github.com/petkaantonov/bluebird
Qhttps://github.com/kriskowal/q
constp=newPromise(function(resolve,reject){// (A)···if(···){resolve(value);// success}else{reject(reason);// failure}});
constpromise=returnPromise();promise.then(functionfulfilled(result){console.log(result);},functionrejected(){// handle rejected promise});
Accepts two callbacks parameters
→ In case something different from a function is passed as parameter, thatthen() is ignored and the Promise chain continues.
constp=Promise.resolve(3).then(x=>{}).then(x=>{console.log(x);});pinstanceofPromise// true
Promise.resolve(3).then(x=>{}).then(x=>{console.log(x);});
Promise.resolve(3).then(x=>{return4;}).then(x=>{console.log(x);// 4});
// same as code aboveconstp=Promise.resolve(3).then(x=>{return4;});// p contains a resolved promise with the value 4p.then(x=>{console.log(x);// 4});
Promise.resolve(3).then(x=>{returnPromise.resolve(4);}).then(x=>{console.log(x);});Promise.resolve(3).then(x=>{returnPromise.reject('ooops');}).then(x=>{console.log(x);}).catch(e=>{console.log(e);});
Promise.resolve(3).then(x=>{thrownewError(‘omg’);return4;}).then(x=>{console.log(x);},e=>{console.log(e);});
promise.then(null,error=>{/* rejection */});
Above code is the same as the code below:
promise.catch(error=>{/* rejection */});
done() is implemented in some libraries, but not in ES6 Promises at the moment.
Accepts an iterable as parameter.
Returns a Promise that:
- Is fulfilled if all elements in iterable are fulfilled
- Fulfillment value: Array with fulfillment values
- Is rejected if any of the elements are rejected
- Rejection value: first rejection value
Promise.all([asyncFunc1(),asyncFunc2()]).then((results)=>{···}).catch(err=>{// Receives first rejection among the Promises···});
NativeArray.prototype.map() can be used:
constfileUrls=['http://example.com/file1.txt','http://example.com/file2.txt',];constpromisedTexts=fileUrls.map(httpGet);Promise.all(promisedTexts).then(texts=>{for(consttextoftexts){console.log(text);}}).catch(reason=>{// Receives first rejection among the Promises});
Accepts an iterable as parameter.
The first element of iterable that is settled is used to settle the returned Promise.
Promise.race([httpGet('http://example.com/file.txt'),delay(5000).then(function(){thrownewError('Timed out')});]).then(text=>{ ...}).catch(reason=>{// Receives first rejection among the Promises});
- Value
- Promise
- Thenable
Ifx is a value:
Promise.resolve('abc').then(x=>console.log(x));// abc
Ifx is a Promise whose constructor is the receiver then x is returned unchanged:
constp=newPromise(()=>null);console.log(Promise.resolve(p)===p);// true
Ifx is athenable, it is converted to a Promise.
→Athenable is an object that has a Promise-style then() method.
Promise.resolve(x) makes sure we get a Promise result, so we can get a normalized, safe result we'd expect.
Returns a Promise that is rejected with err:
constmyError=newError('Problem!');Promise.reject(myError).catch(err=>console.log(err===myError));// true
In the code belowp1 andp2 have a rejected promise with the reason'Ooops'.
varp1=newPromise(function(resolve,reject){reject('Oops');});varp2=Promise.reject('Oops');
// `foo(..)`, `STEP2(..)` and `STEP3(..)` are// all promise-aware utilitiesvarp=foo(42).then(STEP2).then(STEP3);p.catch(handleErrors);
If any step of the chain in fact does its own error handling (perhaps hidden/abstracted away from what you can see),handleErrors(..) won't be notified.
Promises by definition only have a single fulfillment value or a single rejection reason.
Promise.resolve(3).then(x=>{return[1,2];}).then(function(msgs){constx=msgs[0];consty=msgs[1];console.log(x,y);});
Promise.resolve(3).then(x=>{return{a:1,b:2};}).then(x=>{consta=x.a;constb=x.b;console.log(a,b);});
Using ES6 destructuring we can avoid some boilerplate :
Promise.resolve(3).then(x=>{return[1,2];}).then(([x,y])=>{console.log(x,y);});
Promise.resolve(3).then(x=>{return{a:1,b:2};}).then(({ a, b})=>{console.log(a,b);});
Once you create a Promise and register a fulfillment and/or rejection handler for it, there's nothing external you can do to stop that progression.
As a convention, usually a Promise is returned if no callback is passed.
collection.find().toArray((err,docs)=>{if(err){// err handling}console.log(docs):});
collection.find().toArray().then(docs=>{console.log(docs);},err=>{// err handling});
constp=Promise.resolve()p.then(functiona(){p.then(functionc(){console.log('C');});console.log('A');});console.log('D');p.then(functionb(){console.log('B');});console.log('F');
constdoSomethingElse=()=>{returnPromise.resolve('hola');};constfinalHandler=(message)=>{console.log(message);};
Promise.resolve().then(()=>{returndoSomethingElse();}).then(finalHandler);
constdoSomethingElse=()=>{returnPromise.resolve('hola');};constfinalHandler=(message)=>{console.log(message);};
Promise.resolve().then(()=>{doSomethingElse();}).then(finalHandler);
constdoSomethingElse=()=>{returnPromise.resolve('hola');};constfinalHandler=(message)=>{console.log(message);};
Promise.resolve().then(doSomethingElse()).then(finalHandler);
constdoSomethingElse=()=>{returnPromise.resolve('hola');};constfinalHandler=(message)=>{console.log(message);};
Promise.resolve().then(doSomethingElse).then(finalHandler);
Promise.resolve('hola').then(functionfulfilled(msg){msg.type.error;console.log(msg);},functionrejected(err){console.log('caught error:',err);});
Promise.resolve('hola').then(functionfulfilled(msg){msg.type.error;console.log(msg);}).catch(functionrejected(err){console.log('caught error:',err);});
You Don't Know JS: Async & Performance (Kyle Simpson)https://github.com/getify/You-Dont-Know-JS/blob/master/async%20%26%20performance/ch3.md
Exploring ES6 (Axel Rauschmayer)http://exploringjs.com/es6/ch_promises.html
pouchdb blog: We have a problem with promises (Nolan Lawson)https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html
JavaScript reference documentationhttps://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
About
Workshop about ES6 native Promises
Topics
Resources
Uh oh!
There was an error while loading.Please reload this page.



