Top Banner
Angular.JS, I Promise Uri Shaked, Jan 2014 Jan, 2014 Copyright 2013, 2014, Uri Shaked
27

Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Dec 13, 2018

Download

Documents

vuongthu
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS,

I Promise Uri Shaked, Jan 2014

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 2: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

SECTION 1

WHY PROMISES?

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 3: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Synchronous Approach

Consider the following Pseudo Code:

fileName = prompt('Please enter a file name');

if (fileName) {

data = loadUrl('http://server/pictureService');

fs = requestFileSystem(…);

file = fs.getFile(fileName);

file.write(data);

alert('Your changes were saved!');

}

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 4: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Asynchronous Version

This is what it would look like in the async world of JS:

showPrompt("Please enter a file name", function(fileName) {

loadData("http://www.server/pictureService",

function(data) {

requestFileSystem(…, function(fs) {

fs.getFile(fileName, function(file) {

file.write(data, function() {

showAlert("You changes were saved!");

});

});

});

});

});

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 5: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

• Nesting makes the Async version hard to read –

Pyramid Code

• We could split into many functions, but the control flow

would be hard to follow

• The Async version doesn’t even have any error handling

code and yet it is so messy

• Would you enjoy reading and maintaining code like this?

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 6: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

SECTION 2

PROMISES TO RESCUE

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 7: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Definition

A promise represents a future value, usually a future result

of an asynchronous operation, and allows us to define what

will happen once this value becomes available, or when an

error occurs.

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 8: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Basic Usage Pattern

var promise = asyncFunction(parameters);

promise.then(

function (result) {

// Do Something with the result

},

function (error) {

// Handle error (exception, etc).

});

Success Handler

Error Handler

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 9: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

AngularJS 1.2 Extensions

var promise = asyncFunction(parameters);

promise.then(

function (result) {

// Do Something with the result

},

function (error) {

// Handle error (exception, etc).

},

function (update) {

// Receive progress updates (e.g.

// amount of data downloaded so far)

});

Success Handler

Error Handler

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Progress Handler

Page 10: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Catch and Finally

var promise = asyncFunction(parameters);

promise.catch(function (error) {

// Syntax sugar for defining an error handler

});

promise.finally(function() {

// Will be executed regardless of success/failure.

});

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 11: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

The Power of Promises

• You can chain them to create code flows

• Error propagates, so you can catch it on the end of the

chain

• Actually, they are much like an asynchronous equivalent

for the well-known try-catch-finally clause.

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 12: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Chaining Promises

var finalResult = getCurrentUserId()

.then(function (userId) {

if (!userId) { throw "Invalid User"; }

return loadUserData(userId);

}).then(function(userData) {

if (!userData) { return "default.png"; };

return prepareUserThumbnail(userData.profilePic);

}).then(function(thumbnail) {

console.log("User thumbnail: " + thumbnail);

return thumbnail;

}, function(error) {

// Handle error (exception, etc).

});

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 13: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

SECTION 3

USING ANGULAR PROMISES

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 14: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

$HTTP Returns a Promise

function promiseCtrl($scope, $http) {

$http.get("/README.txt").then(function(result) {

$scope.readme = result.data;

});

}

<div ng-controller="promiseCtrl">

<h2>HTTP Request Demo</h2>

<pre>{{readme || "Loading…"}}</pre>

<b ng-show="readme">Request finished.</b>

</div>

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 15: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Promise Chaining

function promiseCtrl($scope, $http) {

$http.get("/userInfo.json").then(function(result) {

var user = $result.data;

$scope.user = user;

return $http.get("/users/" + user.id + "/score”);

}).then(function(result) {

$scope.score = result.data.total;

});

}

<div ng-controller="promiseCtrl">

<p>User: {{user.name}}</p>

<p>Score: {{score}}</p>

</div>

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 16: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

$timeout and $interval Jan, 2014 Copyright 2013, 2014, Uri Shaked

• $timeout(fn, delay) -> Promise

$timeout returns a promise that will be resolved once the

timeout is reached.

• $interval(fn, delay, count) -> Promise

$interval returns a promise which will be notified on each

iteration and will be resolved after count iterations if

count > 0.

Page 17: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

$timeout Example

function promiseCtrl($scope, $timeout, $http) {

$timeout(function(){

return $http.get("/status");

}, 1000).then(function(result) {

$scope.result = result.data

});

}

<div ng-controller="promiseCtrl">

{{result || "Preparing…"}

</div>

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 18: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

SECTION 4

$Q, A FACTORY OF PROMISES

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 19: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Create Your Own

function requestFS(type, size) {

var deferred = $q.defer();

webkitRequestFileSystem(type, size,

function(fs) {

$rootScope.$apply(function() {

deferred.resolve(fs);

});

}, function (fsError) {

$rootScope.$apply(function() {

deferred.reject(fsError);

});

});

return deferred.promise;

}

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 20: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Wrapping as a Promise

You can wrap any value with a promise, using the utility

method $q.when().

$q.when(promise) → promise

$q.when(nonPromise) → a new promise, that will

asynchronously resolve to the given value nonPromise.

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 21: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Get & Return a Promise

function getFile(fs, name, options) {

var deferred = $q.defer();

$q.when(fs).then(function(resolveFS) {

resolveFS.getFile(name, options, function (file) {

$rootScope.$apply(function() {

deferred.resolve(file);

});

}, function (error) {

$rootScope.$apply(function() {

deferred.reject(error);

});

});

});

return deferred.promise;

}

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 22: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Usage Example

// Assume we also implemented readFileAsText() in a similar

// fashion.

function fileExampleCtrl($scope) {

var fs = requestFS(window.PERSISTENT, 1024*1024);

var file = getFile(fs, "log.txt");

readFileAsText(file).then(function(content) {

$scope.content = content;

});

}

<div ng-controller="fileExampleCtrl">

{{ content || 'Loading…' }}

</div>

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 23: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Promise Many

• Sometimes you want to wait for multiple promises

• Angular provide a utility method:

$q.all([promise, …]) → newPromise

• newPromise will resolve once all the given promises have

been resolved

• If any of the given promises is rejected, newPromise will

also be rejected

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 24: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Notify (Angular 1.2)

function downloadUserProfiles(users) {

var deferred = $q.defer(), promises = [];

angular.forEach(users, function(user) {

promises.push(

$http.get("/profile/" + user)

.then(function(result) {

deferred.notify(user);

return result.data;

}));

});

$q.all(promises).then(function(results) {

deferred.resolve(results);

});

return deferred.promise;

}

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 25: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Gotcha’s

• You always want to call deferred.reject() and

deferred.resolve() within a scope context (e.g.

$rootScope.$apply()).

• Remember, you can resolve/reject a promise only once!

• Don’t forget to return deferred.promise

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 26: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

About the Speaker

Uri Shaked, [email protected]

• Co-Organizer of Google Developer Group Tel-Aviv

• Salsa Instructor&Dancer, created the Salsa Beat Machine

• Musician, created the Zampoña mobile pan-flute app

• Loves to hack Electronics and Hardware

Jan, 2014 Copyright 2013, 2014, Uri Shaked

Page 27: Angular.JS, I Promise - s3.amazonaws.com · Angular.JS, I Promise! •Nesting makes the Async version hard to read – ...

Angular.JS, I Promise!

Hope You Enjoyed !

Jan, 2014 Copyright 2013, 2014, Uri Shaked