meet.js promises

104
Promises, Promises @krzychukula krzychukula.blogspot.com

Upload: krzychukula

Post on 27-Jun-2015

160 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Meet.js promises

Promises, Promises

@krzychukulakrzychukula.blogspot.com

Page 2: Meet.js promises
Page 3: Meet.js promises

Beware

● Code examples inspired by: Q.js

● Mixing polish and english

● May be complately wrong

● 20min is not enough!

Page 4: Meet.js promises
Page 5: Meet.js promises

The Pyramid of Doom

Page 6: Meet.js promises

How async code looks like?

Page 7: Meet.js promises

function onInitFs(fs) {

fs.root.getFile('foo.txt', {}, function(fileEntry) {

}, errorHandler);

}

Page 8: Meet.js promises

function onInitFs(fs) {

fs.root.getFile('foo.txt', {}, function(fileEntry) {

fileEntry.file(function(file) { }, errorHandler);

}, errorHandler);

}

Page 9: Meet.js promises

function onInitFs(fs) {

fs.root.getFile('foo.txt', {}, function(fileEntry) {

fileEntry.file(function(file) { var reader = new FileReader();

reader.onloadend = function(e) { var txtArea = document.createElement('textarea'); txtArea.value = this.result; document.body.appendChild(txtArea); };

reader.readAsText(file); }, errorHandler);

}, errorHandler);

}

Page 10: Meet.js promises

function onInitFs(fs) {

fs.root.getFile('foo.txt', {}, function(fileEntry) {

fileEntry.file(function(file) { var reader = new FileReader();

reader.onloadend = function(e) { function onInitFs(fs) {

fs.root.getFile('foo.txt', {}, function(fileEntry) {

fileEntry.file(function(file) { var reader = new FileReader();

reader.onloadend = function(e) { var txtArea = document.createElement('textarea'); txtArea.value = this.result; document.body.appendChild(txtArea); };

reader.readAsText(file); }, errorHandler);

}, errorHandler);};

reader.readAsText(file); }, errorHandler);

}, errorHandler);

}

Page 11: Meet.js promises

JS without Promises

Page 12: Meet.js promises

Nicer abstraction on File API

readFoo(success, error)

Page 13: Meet.js promises

Write test to check read/write

writeFoo(function(){

readFoo(function(text){

expect(text).toBe('foo');

}, error)

}, error)

Page 14: Meet.js promises

writeFoo(function(){

readFoo(function(text){

expect(text).toBe('foo');

}, error)

}, error)

Page 15: Meet.js promises

Start again with promises

writeFoo()//==> returns promise

writeFoo().done(success, error)

Page 16: Meet.js promises

Not enough

writeFoo().done(function(){

readFoo().done(function(text){

expect(text).toBe('foo');

}, error)

}, error)

Page 17: Meet.js promises
Page 18: Meet.js promises

Promises

Page 19: Meet.js promises

Let's learn it!

var promise = writeFoo()

Page 20: Meet.js promises

Promise what it is?

Page 21: Meet.js promises

Object

Promise

Page 22: Meet.js promises

With State

Promise state

Page 23: Meet.js promises

Subscribe to state changes

Promise

then

donefail

Page 24: Meet.js promises

State

Promise

pending

resolved

rejected

state

Page 25: Meet.js promises

Subscribe to state

done(success, error)

resolved rejected

Page 26: Meet.js promises

Just like done*

then(success, error)

resolved rejected

Page 27: Meet.js promises

Only fail handler

fail(error)

resolved rejected

Page 28: Meet.js promises

See it in practice

var promise = writeFoo();

promise.done(success, error)

Page 29: Meet.js promises

Many listeners

Page 30: Meet.js promises

You can attach listeners to it

var promise = writeFoo()

promise.done(success, error)

Page 31: Meet.js promises

Many listeners for one promise!

var promise = writeFoo()

promise.done(log, logError)

promise.done(updateStats, error)

promise.done(displayInfo, displayError)

Page 32: Meet.js promises

Callback

writeFoo(funciton(data){

log(data);

updateStats(data);

displayInfo(data);

}, error)

Page 33: Meet.js promises

Many listeners for one promise!

function writeFooAndLog(){var promise = writeFoo()promise.done(log, error)return promise;

}

var promise = writeFooAndLog();

promise.done(successDialog, errorDialog)

Page 34: Meet.js promises

Promise lifetime

Page 35: Meet.js promises

Attach listeners even when it's done!

var promise = readFoo()

promise.done(log, error)

==> resolves with cache...

Page 36: Meet.js promises

You know, order matters!

var img = new Image();

img.src = "sprite.png";

img.onload = function(){ //never called

}

Page 37: Meet.js promises

Promise is persistent

Page 38: Meet.js promises

What if...

var img = new Image();

var promise = img.load("sprite.png");

promise.done(function(){ })

Page 39: Meet.js promises

Attach listeners even when it's done!

var promise = readFoo()

promise.done(log, error)

==> resolves with cache... promise.done(updateStats, error)promise.done(displayInfo, error)

Page 40: Meet.js promises

The same is true for fails

var promise = writeFoo()

promise.done(log)

promise.fail(revertTransaction)

promise.fail(logError)

Page 41: Meet.js promises

Before we go deeper

Promise can change state only once.

Page 42: Meet.js promises

Chains

Page 43: Meet.js promises

jQuery API example

$('widget')

Page 44: Meet.js promises

$('widget').addClass('important')

Page 45: Meet.js promises

$('widget').addClass('important').show()

Page 46: Meet.js promises

$('widget').addClass('important').show().find('h1')

Page 47: Meet.js promises

Chaining

$('widget').addClass('important').show().find('h1').text('Special Offers')

Page 48: Meet.js promises

Then

Page 49: Meet.js promises

Similar to done

.done(asyncSuccess, error)

.then(asyncSuccess, error)

Page 50: Meet.js promises

Difference

.done(asyncSuccess, error)//==> undefined

.then(asyncSuccess, error)//==> promise

Page 51: Meet.js promises

Create chains for async

promise.then(asyncSuccess, error).then(syncSuccess2, error2)

Page 52: Meet.js promises

Then always returns new promise

promise.then(success, error).then(success2, error2)//==> promise

Page 53: Meet.js promises

Then and errors!

promise.then(success , error).then(success2 , error2).then(success3 , error3).then(success4, error4);

* not in jQuery

Page 54: Meet.js promises

Then and errors!

promise.then(succes).then(success2).then(success3).then(success4, fail);

Page 55: Meet.js promises

So 'then' is a better 'done'

then > done

* at least I thinked so...

Page 56: Meet.js promises

Let's fix this test example

Page 57: Meet.js promises

The one with pyramid

writeFoo().done(function(){

readFoo().done(function(text){

expect(text).toBe('foo');

}, error)

}, error)

Page 58: Meet.js promises

But start from scratch.

writeFoo()

Page 59: Meet.js promises

writeFoo().then(readFoo)

Page 60: Meet.js promises

writeFoo().then(readFoo).then(function(text){

//==> content of foo file}, error);

Page 61: Meet.js promises

Final Test Example*

writeFoo().then(readFoo).then(function(text){

expect(text).toBe('foo');}, fail);

Page 62: Meet.js promises

Troubles

Page 63: Meet.js promises

When I was starting

I've put promises everywhere!

I've used then - because it's better

Page 64: Meet.js promises

I got some

Broken scripts

No errors in console

WAT!

Time for debugger...

Page 65: Meet.js promises

Reason: Stupid typo

then(showLenght)

then(showLength)

Page 66: Meet.js promises
Page 67: Meet.js promises

but wait...

when in trouble

Promises considered harmful!

Page 68: Meet.js promises
Page 69: Meet.js promises

Q.js Readme

return foo().then(

function (value) { throw new Error("Can't bar.");

},function (error) { // We only get here if "foo" fails}

);

Page 70: Meet.js promises

Error handler AFTER callback

return foo().then(function (value) { throw new Error("Can't bar.");}).fail(function (error) { // We get here with any callback error});

Page 71: Meet.js promises

Why?

.then()//=> promise

1: Then always returns promise

Page 72: Meet.js promises

Why?

.then()//=> promise

1: Then always returns promise2: Promise catches all errors

Page 73: Meet.js promises

Why?

.then()//=> promise

1: Then always returns promise2: Promise catches all errors3: And passes them to the last promise

Page 74: Meet.js promises

fail fast

writeFoo().then(readFoo).then(function(text){

expect(text).toBe('foo');}, fail).done();//==>undefined

Page 75: Meet.js promises

So we can fix test example

writeFoo().then(readFoo).then(function(text){

expect(text).toBe('foo');}, fail);//==> promise

Page 76: Meet.js promises

Done! :)

writeFoo().then(readFoo).done(function(text){

expect(text).toBe('foo');}, fail);//==>undefined

Page 77: Meet.js promises

Deferred

Page 78: Meet.js promises

Deferred

How can I change state of promise?

Page 79: Meet.js promises

Deferred Promise

Page 80: Meet.js promises

Deferred Promise

READONLY

Master of promise

Page 81: Meet.js promises

Deferred Promise

READONLY

resolve reject

Page 82: Meet.js promises

Show me the code

function getFoo(){var deferred = Q.defer();FS.readFile("foo.txt", function (error, text) { if (error) { deferred.reject(new Error(error)); } else { deferred.resolve(text); }});return deferred.promise;

}

Page 83: Meet.js promises

Create Deferred

function getFoo(){var deferred = Q.defer();FS.readFile("foo.txt", function (error, text) { if (error) { deferred.reject(new Error(error)); } else { deferred.resolve(text); }});return deferred.promise;

}

Page 84: Meet.js promises

Return promise from deferred

function getFoo(){var deferred = Q.defer();FS.readFile("foo.txt", function (error, text) { if (error) { deferred.reject(new Error(error)); } else { deferred.resolve(text); }});return deferred.promise;

}

Page 85: Meet.js promises

success == resolve

function getFoo(){var deferred = Q.defer();FS.readFile("foo.txt", function (error, text) { if (error) { deferred.reject(new Error(error)); } else { deferred.resolve(text); }});return deferred.promise;

}

Page 86: Meet.js promises

error == reject

function getFoo(){var deferred = Q.defer();FS.readFile("foo.txt", function (error, text) { if (error) { deferred.reject(new Error(error)); } else { deferred.resolve(text); }});return deferred.promise;

}

Page 87: Meet.js promises

Wrap it in function

function getFoo(){var deferred = Q.defer();FS.readFile("foo.txt", function (error, text) { if (error) { deferred.reject(new Error(error)); } else { deferred.resolve(text); }});return deferred.promise;

}

Page 88: Meet.js promises

getFoo().then(joinLines).then(displayContent, showError).done();

Page 89: Meet.js promises

All

Page 90: Meet.js promises

3 simultaneous calls

3 ajax calls at once

Page 91: Meet.js promises

Without pyramid

Page 92: Meet.js promises

without call counting

var ajaxCalls = 3;

success: function(){if(--ajaxCalls == 0) letUserKnow

Page 93: Meet.js promises

var promise1 = $.ajax(one);var promise2 = $.ajax(two);var promise3 = $.ajax(three);

Q.all([promise1, promise2, promise3]).done(letUserKnow);

Page 94: Meet.js promises

var promise1 = $.ajax();var promise2 = $.ajax();var promise3 = $.ajax();

Q.all([promise1, promise2, promise3]).done(letUserKnow)

Page 95: Meet.js promises

var promise1 = $.ajax();var promise2 = $.ajax();var promise3 = $.ajax();

Q.all([promise1, promise2, promise3]).done(letUserKnow);

Page 96: Meet.js promises

var promise1 = $.ajax();var promise2 = $.ajax();var promise3 = $.ajax();

Q.all([promise1, promise2, promise3]).done(letUserKnow);

Page 97: Meet.js promises

Summary

Page 98: Meet.js promises

InitFs()

.then(getFile('foo.txt', {}))

.then(openFile)

.then(readAsText)

.done(displayInTextarea, errorHandler)

Page 99: Meet.js promises

Many listeners for one promise!

var promise = writeFoo()

promise.done(log)promise.done(updateStats)

promise.fail(logError)promise.fail(displayError)

Page 100: Meet.js promises

You can chain promises with 'then'

promise.then(succes).then(success2).then(success3).then(success4, fail);

Page 101: Meet.js promises

When You See No Errors

.done()

Page 102: Meet.js promises

Only 2 slides till the end ;)

Thanks for listening!

Page 104: Meet.js promises

The end

Let me know how I can be better:

@krzychukula