Skip to content

Instantly share code, notes, and snippets.

@grahamjenson
Last active January 4, 2016 15:49
Show Gist options
  • Select an option

  • Save grahamjenson/8643013 to your computer and use it in GitHub Desktop.

Select an option

Save grahamjenson/8643013 to your computer and use it in GitHub Desktop.
Lightning Promises Talk
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/extensions/goto/deck.goto.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/extensions/menu/deck.menu.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/extensions/navigation/deck.navigation.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/extensions/status/deck.status.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/extensions/scale/deck.scale.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/themes/style/swiss.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/isagalaev/highlight.js/master/src/styles/monokai_sublime.css">
<link rel="stylesheet" href="https://rawgithub.com/imakewebthings/deck.js/master/core/deck.core.css">
<link rel="stylesheet" media="screen" href="https://rawgithub.com/imakewebthings/deck.js/master/themes/transition/horizontal-slide.css">
<script src='http://code.jquery.com/jquery-2.0.3.js'></script>
<script src='http://code.jquery.com/ui/1.10.3/jquery-ui.js'></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/modernizr.custom.js"></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/core/deck.core.js"></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/extensions/menu/deck.menu.js"></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/extensions/goto/deck.goto.js"></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/extensions/status/deck.status.js"></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/extensions/navigation/deck.navigation.js"></script>
<script src="https://rawgithub.com/imakewebthings/deck.js/master/extensions/scale/deck.scale.js"></script>
<script src="http://coffeescript.org/extras/coffee-script.js"></script>
<script src="http://yandex.st/highlightjs/8.0/highlight.min.js"></script>
<link href='http://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css' />
<style>
pre {
border: 0px;
}
.body {
font-family: "Lato", sans-serif;
color: #5d5d5d; }
.pull-right {
float: right;
margin: 10px; }
.pull-left {
float: left;
margin: 10px; }
</style>
</head>
<body>
<div class="deck-container">
<!-- Begin slides. Just make elements with a class of slide. -->
<section class='slide'>
<h1>
Promises
<br>
<span style="font-size: .2em; color: #c00;"> I promise this will be short </span>
</h1>
</section>
<section class='slide'>
<h1>
<span style="font-size: .2em; color: #c00;">... but first</span>
<br>
Deferred Objects
</h1>
</section>
<section class="slide">
<div class=''>
<h2>Deferred Objects</h2>
<h3> State </h3>
<p>
Describes the state of availability of something,
</p>
<p>
<pre>
<code class='javascript'>
$.Deferred().state() // 'pending'
$.Deferred().resolve().state() // 'resolved'
$.Deferred().reject().state() // 'rejected'
</code>
</pre>
</p>
</div>
</section>
<section class="slide">
<div class=''>
<h2>Deferred Objects</h2>
<h3> Callbacks </h3>
<p>
Can attach callbacks with <code>done</code>, <code>fail</code> and <code>always</code>
</p>
<p>
<pre>
<code class='javascript'>
log = function () {
console.log(Array.prototype.slice.call(arguments).join(' '))
} // logs the functions arguments
d = $.Deferred()
d.done(log)
d.resolve('maorigeek') // maorigeek
</code>
</pre>
</p>
</div>
</section>
<section class="slide">
<h2>Deferred Objects</h2>
<h3> Order of Callbacks</h3>
<div class=''>
<p>
callbacks are executed with correct arguments after the state has changed
</p>
<p>
<pre>
<code class='javascript'>
d = $.Deferred()
d.resolve('maorigeek')
d.done(log) // maorigeek
</code>
</pre>
</p>
</div>
</section>
<section class="slide">
<h2>Deferred Objects </h2>
<h3> Chaining</h3>
<div class=''>
<p>
<code>done</code>, <code>fail</code> and <code>always</code> return original deferred
</p>
<p>
<pre>
<code class='javascript'>
d = $.Deferred().done(log).resolve('maorigeek') // maorigeek
</code>
</pre>
</p>
</div>
</section>
<section class='slide'>
<h1>
<span style="font-size: .2em; color: #c00;">... now</span>
<br>
Promises
</h1>
</section>
<section class="slide">
<h2> Promises </h2>
<div class=''>
<p>
A promise is a deferred object that does not let you change its state, only attach callbacks
</p>
<p>
You return a promise so that others cannot break it
</p>
<p>
<pre>
<code class='javascript'>
d = $.Deferred().promise()
</code>
</pre>
</p>
</div>
</section>
<section class="slide">
<h2>Promises </h2>
<h3> when </h3>
<div class=''>
<p>
<code>$.when</code> is a helper function that takes deferred objects and/or variables and returns a promise that is their logical AND
</p>
<p>
<pre>
<code class='javascript'>
d = $.Deferred()
$.when(d, 'World').done(log)
d.resolve('Hello') // Hello World
</code>
</pre>
</p>
</div>
</section>
<section class="slide">
<h2>Promises </h2>
<h3> then </h3>
<div class=''>
<p>
<code>then</code> is a function on a promise that takes callbacks for resolved and failed and returns a new promise
</p>
<p>
<pre>
<code class='javascript'>
gate = $.Deferred()
promise = $.when('Hello').then(function(h) { return $.when(h,gate) } )
promise.done(log)
gate.resolve('World') // Hello World
</code>
</pre>
</p>
</div>
</section>
<section class='slide'>
<h1>
Why Promises?
<br>
<span style="font-size: .2em; color: #c00;">clean, asynchronous code</span>
</h1>
</section>
<section class="slide">
<h2>Promises Examples </h2>
<h3> the bad, the ugly and the good </h3>
<div class=''>
<p>
Why should you use them? Given the contrived (stolen) example of requiring to wait for some asynchronous requests to render a sidebar... some possible solutions to that problem...
</p>
</div>
</section>
<section class="slide">
<h2>Promises Examples </h2>
<h3> the bad </h3>
<div class=''>
<p>
A series of ajax calls
</p>
<p>
<pre>
<code class='javascript'>
$.ajax({
success: function() {
$.ajax({
//Yo Dawg, I heard you like callbacks...
}
});
</code>
</pre>
</p>
</div>
</section>
<section class="slide">
<h2>Promises Examples </h2>
<h3> the ugly </h3>
<div class=''>
<p>
A callback that registers itself as complete
</p>
<p>
<pre>
<code class='javascript'>
var ugly_promise = [];
$.ajax({ success: function() { ugly_promise.push('resolved'); check();}});
$.ajax({ success: function() { ugly_promise.push('resolved'); check();}});
var check = function() {
//checks for al 2 values in the completed array, then
//render sidebar
}
</code>
</pre>
</p>
</div>
</section>
<section class="slide">
<h2>Promises Examples </h2>
<h3> the good </h3>
<div class=''>
<p>
A series of ajax calls
</p>
<p>
<pre>
<code class='javascript'>
var p1 = $.ajax({});
var p2 = $.ajax({});
render_side_bar = function(ret1, ret2){
//render sidebar
}
render_no_side_bar = function(){}
$.when(p1, p2).then(render_side_bar, render_no_side_bar)
</code>
</pre>
</p>
</div>
</section>
<section class='slide'>
<h1>
Fun with Promises
<br>
<span style="font-size: .2em; color: #c00;">stuff to do at work when bored</span>
</h1>
</section>
<section class="slide">
<h2>Complex animations </h2>
<h3> hide, show, render, hide </h3>
<div class=''>
<p>
<pre>
<code class='javascript'>
$('body'). toggle('blinds').promise().then(function(){$('body').toggle('blinds')})
</code>
</pre>
</p>
</div>
</section>
<section class="slide">
<h2>Waiting </h2>
<h3> hold on a second </h3>
<div class=''>
<p>
<pre>
<code class='javascript'>
function wait(ms) {
var deferred = $.Deferred();
setTimeout(deferred.resolve(), ms);
return deferred.promise();
}
wait(1500).then(function () {
// After 1500ms this will be executed
});
</code>
</pre>
</p>
</div>
</section>
<section class="slide">
<h2>Handling a queue of incoming events </h2>
<h3>this may not be a good idea </h3>
<div class=''>
<p>
<pre>
<code class='javascript'>
window.queue = $.when()
$('#list').on('click', function() {
window.queue = window.queue.then(function() {
//do the thing
})
}
)
</code>
</pre>
</p>
</div>
</section>
<section class="slide">
<div class=''>
<iframe scrolling="no" src="http://bl.ocks.org/grahamjenson/raw/8309901/" style="width: 100%; height: 100%;"></iframe>
</div>
</section>
<section class="slide">
<h2>Back on promise</h2>
<h3>Backbone with (more) promises </h3>
<div class=''>
<p>
<pre>
<code class='coffeescript'>
class Posts extends Backbone.Collection
url: -> 'http://user/#{@user.id}/posts
model: Post
class User extends BOP.BOPModel
@has 'posts', Posts, method: 'fetch', reverse: 'user'
user = new User(id: 1)
$.when(user.get('posts')).done( (posts) -> #render posts)
</code>
</pre>
</p>
</div>
</section>
<section class='slide'>
<h1>
Why the hate?
<br>
<span style="font-size: .2em; color: #c00;">some things about common.js and Promises/A+</span>
</h1>
</section>
<section class="slide">
<h2>JQuery doesn't have 'real' promises</h2>
<h3>it doesnt support errors</h3>
<div class=''>
<p>
Many people see promises as being a nicer way to handle async. code. One of the things it can handle, but JQuery doesnt, is errors.
</p>
<p>
<pre>
<code class='javascript'>
d = $.Deferred()
d.then(function(){throw new Error('err')}).fail(function(){console.log('fail')})
d.resolve() // throws Error: err, instead of calling fail with the exception
</code>
</pre>
</p>
</div>
</section>
<section class="slide">
<h2>You're Missing the Point of Promises</h2>
<h3>Domenic Denicola (author of the Q promise library)</h3>
<div class=''>
<blockquote>
<p>they have a fail [sic] flaw in their chaining implementation, which is that they don’t do thrown exception handling at all. So the whole abstraction breaks down when you can no longer throw an exception and have it turn into a rejected promise</p>
</blockquote>
<p>
The Promises/A+ spec which comes with tests, to create interoperable tests for promises
</p>
</div>
</section>
<section class='slide'>
<h1>
You should use/learn promises
<br>
<span style="font-size: .2em; color: #c00;">they will be in ES6 nativly</span>
</h1>
</section>
<section class="slide">
<h2>About me</h2>
<div class=''>
<ul>
<li>Graham Jenson</li>
<li>Twitter: <strong>@grahamjenson</strong> </li>
<li><strong>Blog:</strong> http://maori.geek.nz/blog</li>
<li><strong>This talk:</strong> http://maori.geek.nz/portfolio</li>
</ul>
</div>
</section>
<!-- deck.navigation snippet -->
<div aria-role="navigation">
<a href="#" class="deck-prev-link" title="Previous">&#8592;</a>
<a href="#" class="deck-next-link" title="Next">&#8594;</a>
</div>
<!-- deck.status snippet -->
<p class="deck-status" aria-role="status">
<span class="deck-status-current"></span>
/
<span class="deck-status-total"></span>
</p>
<!-- deck.goto snippet -->
<form action="." method="get" class="goto-form">
<label for="goto-slide">Go to slide:</label>
<input type="text" name="slidenum" id="goto-slide" list="goto-datalist">
<datalist id="goto-datalist"></datalist>
<input type="submit" value="Go">
</form>
<!-- End extension snippets. -->
</div>
<script>
$(function() {
hljs.initHighlightingOnLoad();
$.deck('.slide');
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment