angular.js, i promise - s3.amazonaws.com · angular.js, i promise! •nesting makes the async...

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

Upload: vuongthu

Post on 13-Dec-2018

231 views

Category:

Documents


0 download

TRANSCRIPT

Angular.JS,

I Promise Uri Shaked, Jan 2014

Jan, 2014 Copyright 2013, 2014, Uri Shaked

SECTION 1

WHY PROMISES?

Jan, 2014 Copyright 2013, 2014, Uri Shaked

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

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

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

SECTION 2

PROMISES TO RESCUE

Jan, 2014 Copyright 2013, 2014, Uri Shaked

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

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

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

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

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

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

SECTION 3

USING ANGULAR PROMISES

Jan, 2014 Copyright 2013, 2014, Uri Shaked

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

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

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.

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

SECTION 4

$Q, A FACTORY OF PROMISES

Jan, 2014 Copyright 2013, 2014, Uri Shaked

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

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

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

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

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

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

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

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

Angular.JS, I Promise!

Hope You Enjoyed !

Jan, 2014 Copyright 2013, 2014, Uri Shaked