You are on page 1of 112

JavaScript Promise

azu / liubinkakuhonnkyou
Revision History
Revision 1.4.1 /

Table of Contents
........................................................................................................................................... 3
........................................................................................................................... 3
................................................................................................................... 3
........................................................................................................................... 4
/License ......................................................................................................... 4
....................................................................................................................... 5
Chapter.1 - Promise ...................................................................................................... 5
Promise .................................................................................................................. 5
Promise ...................................................................................................................... 7
Promise ............................................................................................................ 10
Chapter.2 - Promise ........................................................................................................ 14
Promise.resolve ................................................................................................................ 14
Promise.reject .................................................................................................................. 17
: Promise .............................................................................. 17
Promise#then .................................................................................................................. 20
Promise#catch ................................................................................................................ 28
: thenpromise ........................................... 30
Promise ................................................................................................................ 33
Promise.all ....................................................................................................................... 37
Promise.race .................................................................................................................... 39
then or catch? ................................................................................................................. 41
Chapter.3 - Promise ........................................................................................................ 43
......................................................................................................................... 43
MochaPromise ................................................................................................ 47
controllable tests ............................................................................ 52
Chapter.4 - Advanced ............................................................................................................. 56
PromiseLibrary .................................................................................... 56
Promise.resolveThenable ............................................................................................ 59
rejectthrow ................................................................................................... 68

1
JavaScript Promise

DeferredPromise ......................................................................................................... 71
Promise.racedelayXHR ....................................................................... 76
Promise.prototype.done ................................................................................ 85
Promisemethod chain ............................................................................. 91
Promisesequence ..................................................................... 99
Promises API Reference ....................................................................................................... 107
Promise#then ................................................................................................................ 107
Promise#catch .............................................................................................................. 107
Promise.resolve .............................................................................................................. 108
Promise.reject ................................................................................................................ 108
Promise.all ..................................................................................................................... 109
Promise.race .................................................................................................................. 109
................................................................................................................................... 110
............................................................................................................................... 110
............................................................................................................................... 111
............................................................................................................................... 111
................................................................................................... 112

2
JavaScript Promise

ECMAScript 6 Promises
JavaScriptPromise

PromisePromise

PromisePromise
Promise

ES6 Promises

ES6 PromisesJavaScript
Promise

FirefoxChrome
PromiseES6 PromisesPromises/A+

APIPromise
Promise

JavaScript

JavaScript: The Good Parts 1

JavaScript Patterns 2

JavaScript: The Definitive Guide, 6th Edition 3

Perfect JavaScript 4

1 http://shop.oreilly.com/product/9780596517748.do
2 http://shop.oreilly.com/product/9780596806767.do
3 http://shop.oreilly.com/product/9780596805531.do
4 http://gihyo.jp/book/2011/978-4-7741-4813-7?ard=1400715177

3
JavaScript Promise

Effective JavaScript 5

JavaScriptWebNode.js

Node.jsNode.js

Promise

instance#method

Promise#then Promise then

object.method

JavaScript Promise.all

/License
GitHub

AsciiDoc 6

azu/promises-book 7

MITCC-BY-NC
5 http://books.shoeisha.co.jp/book/b107881.html
6 http://asciidoctor.org/
7 https://github.com/azu/promises-book

4
JavaScript Promise

GitHubIssue

Issues azu/promises-book 8

Issues liubin/promises-book 9

10

GitHub Pull
Requests 11

Chapter.1 - Promise
JavaScriptPromise

Promise

Promise

Promise
PromiseJavaScript

Promise E 12 /

JavaScriptJavaScript Promise

JavaScript

----
getAsync("fileA.txt", function(error, result){
if(error){//
throw error;
}

8 https://github.com/azu/promises-book/issues?state=open
9 https://github.com/liubin/promises-book/issues?state=open
10 https://gitter.im/azu/promises-book
11 https://github.com/azu/promises-book/pulls
12 http://erights.org/elib/distrib/pipeline.html

5
JavaScript Promise

//
});
----
<1> (error )

Node.jsJavaScript Error

Promise

Promise
----
var promise = getAsyncPromise("fileA.txt");
promise.then(function(result){
//
}).catch(function(error){
//
});
----
<1> promise

promise promise

promise

promise( then catch )


Promise

promise
promise

JavaScriptPromise

6
JavaScript Promise

Promise
ES6 Promises API

Constructor

Promise XMLHttpRequest Promise promise

promise new Promise

var promise = new Promise(function(resolve, reject) {


//
// resolve reject
});

Instance Method

newpromise resolve() / reject()


promise.then()

promise.then(onFulfilled, onRejected)

resolve()
onFulfilled
reject()
onRejected

onFulfilled onRejected

promise.then
promise.then(undefined, onRejected) reject
promise.catch(onRejected)

promise.catch(onRejected)

Static Method

Promise

7
JavaScript Promise

Promise.all() Promise.resolve() Promise

Promise workflow

promise-workflow.js

function asyncFunction() {

return new Promise(function (resolve, reject) {


setTimeout(function () {
resolve('Async Hello world');
}, 16);
});
}

asyncFunction().then(function (value) {
console.log(value); // => 'Async Hello world'
}).catch(function (error) {
console.log(error);
});

new Promisepromise
<1>promise .then
asyncFunction promise promise
then resolve catch

promisesetTimeout16msresolve, then
'Async Hello world'

catch promiseresolve
setTimeout
catch

promise.then(onFulfilled, onRejected) catch


then

asyncFunction().then(function (value) {
console.log(value);
}, function (error) {
console.log(error);
});

8
JavaScript Promise

Promise
PromisePromise

new Promise promise

"has-resolution" - Fulfilled
resolve() onFulfilled
"has-rejection" - Rejected
reject() onRejected
"unresolved" - Pending
resolverejectpromise

ES6 Promises
Promises/A+


Promises/A+ 13 Pending Fulfilled Rejected

Figure1.promise states

ECMAScript Language Specification ECMA-262 6th Edition


DRAFT 14 [[PromiseStatus]]
[[PromiseStatus]] API

promise

13 http://promises-aplus.github.io/promises-spec/
14 http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects

9
JavaScript Promise

promisePendingFulfilledRejected promise

PromiseEvent .then

FulfilledRejectedSettled()

Settled
resolve() reject()

PendingSettledPromise/

promise .then

JavaScript Promises - Thinking Sync in an Async World // Speaker


Deck 15 pptPromise

Promise
Promise

promise
promise

1. new Promise(fn) promise


2. fn
resolve()
reject(Error)

promise

PromiseXMLHttpRequest(XHR)

XHRpromise

PromiseXHR getURL

xhr-promise.js

15 https://speakerdeck.com/kerrick/javascript-promises-thinking-sync-in-an-async-world

10
JavaScript Promise

function getURL(URL) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.send();
});
}
//
var URL = "http://httpbin.org/get";
getURL(URL).then(function onFulfilled(value){
console.log(value);
}).catch(function onRejected(error){
console.error(error);
});

getURL XHR200 resolve -


reject

resolve(req.responseText) response resolve


( then
)

Node.js callback(error, response)


errorPromiseresolve/reject
resolveresponse

reject

XHR onerror reject


reject

reject(new Error(req.statusText)); Error


reject Error
Error

11
JavaScript Promise

reject rejectError
200reject reject statusText then
catch

promise

promise

getURL("http://example.com/"); // => promise

Promises Overview promise


promisepromise

promise

promise resolve (onFulfilled)

promise reject (onRejected)

Figure2.promise value flow

getURL

resolve promiseFulFilled

resolve .then

var URL = "http://httpbin.org/get";


getURL(URL).then(function onFulfilled(value){

12
JavaScript Promise

console.log(value);
});

onFulfilled
getURL resolve(req.responseText); promiseresolveFulfilled
onFulfilled


getURL

reject promiseRejected

reject .then .catch

reject

var URL = "http://httpbin.org/status/500";


getURL(URL).then(function onFulfilled(value){
console.log(value);
}).catch(function onRejected(error){
console.error(error);
});

500
onRejected
getURL reject Error
.catch

.catch promise.then(undefined, onRejected)

getURL(URL).then(onFulfilled, onRejected);

onFulfilled, onRejected
.catch resolvereject
thencatch

13
JavaScript Promise

new Promise promise

.then .catch promise

Promise
Promise

Promise
Promise
Promise

Chapter.2 - Promise
Promise

Promise.resolve

new Promise() promise

Promise.resolve Promise.reject

new Promise

Promise.resolve(value) new Promise()

Promise.resolve(42);

new Promise(function(resolve){
resolve(42);
});

resolve(42); promiseresolved
42 then onFulfilled

Promise.resolve(value); promise
.then

Promise.resolve(42).then(function(value){

14
JavaScript Promise

console.log(value);
});

Promise.resolve new Promise() promise

Thenable

Promise.resolve thenable promise

ES6 PromisesThenablepromise

.length Array likethenable


.then

thenablepromisethenable then
Promise then thenable
promisethenable then

thenable jQuery.ajax() 16
thenable

jQuery.ajax() jqXHR Object 17 .then

$.ajax('/json/comment.json');// => `.then`

thenable Promise.resolve promise

promise then catch ES6 Promises

thenablepromise

var promise = Promise.resolve($.ajax('/json/comment.json'));// => promise


promise.then(function(value){
console.log(value);
});

16 https://api.jquery.com/jQuery.ajax/
17 http://api.jquery.com/jQuery.ajax/#jqXHR

15
JavaScript Promise

jQuerythenable
jQuery.ajax() 18 .then jqXHR Object 19
Deferred Object 20

Deferred ObjectPromises/A+ES6 Promises


promise

jQuery Deferred Object 21 then


promise

.then
ES6 Promises

JavaScript Promises: There and back again - HTML5 Rocks 22

You're Missing the Point of Promises 23

https://twitter.com/hirano_y_aa/status/398851806383452160

Promise.resolve then promise

thenable Promise.cast

PromiseThenableend-
user

4Promise.resolveThenable
ThenablePromise.resolve

Promise.resolve
Fulfilledpromisepromise

Promise Promise.resolve promise

18 https://api.jquery.com/jQuery.ajax/
19 http://api.jquery.com/jQuery.ajax/#jqXHR
20 http://api.jquery.com/category/deferred-object/
21 http://api.jquery.com/category/deferred-object/
22 http://www.html5rocks.com/en/tutorials/es6/promises/#toc-lib-compatibility
23 http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/

16
JavaScript Promise

Promise.reject
Promise.reject(error) Promise.resolve(value) new Promise()

Promise.reject(new Error(""))

new Promise(function(resolve,reject){
reject(new Error(""));
});

promisethen onRejected
Error onRejected

Promise.reject(new Error("BOOM!")).catch(function(error){
console.error(error);
});

Promise.resolve(value) promisereject
resolvedebug

: Promise
Promise.resolve(value) promiseresolve
.then

.then

var promise = new Promise(function (resolve){


console.log("inner promise"); // 1
resolve(42);
});
promise.then(function(value){
console.log(value); // 3
});
console.log("outer promise"); // 2

loglog

inner promise // 1
outer promise // 2

17
JavaScript Promise

42 // 3

JavaScript <1>
resolve(42); promise FulFilled
42

promise.then <3>

promise.then promise

promise.then promise
PromisePromise

<2> <3>

Promise

onReady(fn)

mixed-onready.js

function onReady(fn) {
var readyState = document.readyState;
if (readyState === 'interactive' || readyState === 'complete') {
fn();
} else {
window.addEventListener('DOMContentLoaded', fn);
}
}
onReady(function () {
console.log('DOM fully loaded and parsed');
});
console.log('==Starting==');

mixed-onready.jsDOM

18
JavaScript Promise

onReadyDOM

onReadyDOM
DOMContentLoaded

log

async-onready.js

function onReady(fn) {
var readyState = document.readyState;
if (readyState === 'interactive' || readyState === 'complete') {
setTimeout(fn, 0);
} else {
window.addEventListener('DOMContentLoaded', fn);
}
}
onReady(function () {
console.log('DOM fully loaded and parsed');
});
console.log('==Starting==');

Effective JavaScript 24 67






setTimeout
API

David Herman Effective JavaScript

promise.then
Promise Promise

24 http://effectivejs.com/

19
JavaScript Promise

onReady Promise

onready-as-promise.js

function onReadyPromise() {
return new Promise(function (resolve, reject) {
var readyState = document.readyState;
if (readyState === 'interactive' || readyState === 'complete') {
resolve();
} else {
window.addEventListener('DOMContentLoaded', resolve);
}
});
}
onReadyPromise().then(function () {
console.log('DOM fully loaded and parsed');
});
console.log('==Starting==');

Promise
setTimeout

Promise#then
Promise then catch

.then().catch() Promise
method chain

promise

aPromise.then(function taskA(value){
// task A
}).then(function taskB(vaue){
// task B
}).catch(function onRejected(error){
console.log(error);
});

then taskPromise
taskA task B

Promise --
promise chain

20
JavaScript Promise

Promisepromise chain

then promise chain

promise chain

promise chain then catch


promiseonFulfilledonRejected

promise chain -

promise chain

promise-then-catch-flow.js

function taskA() {
console.log("Task A");
}
function taskB() {
console.log("Task B");
}
function onRejected(error) {
console.log("Catch Error: A or B", error);
}
function finalTask() {
console.log("Final Task");
}

var promise = Promise.resolve();


promise
.then(taskA)
.then(taskB)
.catch(onRejected)
.then(finalTask);

promise chain

21
JavaScript Promise

Figure3.promise-then-catch-flow.js

then (onRejected)

then
onFulfilled
catch
onRejected

22
JavaScript Promise

Task A Task B onRejected

Task A Task B onRejected

Rejectedpromise

Promise try-catch
catch

Rejectedpromise
throw promise chain onRejected

4
rejectthrow

promise chain onRejected Final Task catch


Task

Task A onRejected

Task A

Task A TaskA onRejected FinalTask

23
JavaScript Promise

Figure4.Task A

promise-then-taska-throw.js

function taskA() {
console.log("Task A");
throw new Error("throw Error @ Task A")
}

24
JavaScript Promise

function taskB() {
console.log("Task B");//
}
function onRejected(error) {
console.log(error);// => "throw Error @ Task A"
}
function finalTask() {
console.log("Final Task");
}

var promise = Promise.resolve();


promise
.then(taskA)
.then(taskB)
.catch(onRejected)
.then(finalTask);

Task B

taskA throw
onRejected
Rejectedpromise
rejectthrow

promise chain

Task

Task A Task B

Task A return Task B

promise-then-passing-value.js

function doubleUp(value) {
return value * 2;
}
function increment(value) {
return value + 1;
}
function output(value) {
console.log(value);// => (1 + 1) * 2

25
JavaScript Promise

}

var promise = Promise.resolve(1);


promise
.then(increment)
.then(doubleUp)
.then(output)
.catch(function(error){
// promise chain
console.error(error);
});

Promise.resolve(1); promise chain

1. Promise.resolve(1); 1 increment

2. increment +1 return

3. 2 doubleUp

4. output

26
JavaScript Promise

Figure5.promise-then-passing-value.js

return promise

return Promise.resolve(return);
then promise

27
JavaScript Promise

: then
promise

Promise#then
promise

Promise#catch
Promise#then Promise#catch

Promise#catch promise.then(undefined, onRejected);


promiseRejected

Promise#then Promise#catch
then or catch?

IE8

polyfill 25

polyfill
Library jakearchibald/es6-promise 26

Promise#catch

var promise = Promise.reject(new Error("message"));

25 https://github.com/jakearchibald/es6-promise
26 https://github.com/jakearchibald/es6-promise

28
JavaScript Promise

promise.catch(function (error) {
console.error(error);
});

IE8 identifier not


found

catch ECMAScript 27 (Reserved Word)

ECMAScript 3 IE8
ECMAScript 3 catch
promise.catch() identifier not found

ECMAScript 5ECMAScript 5
IdentifierName 28

ECMAScript5 Identifier 29
for
for
object.for for

ECMAScript 3

dot notation 30 ECMAScript 3

bracket notation 31

IE8
polyfill

Promise#catch

27 http://mothereff.in/js-properties#catch
28 http://es5.github.io/#x7.6
29 http://es5.github.io/#x7.6
30 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/
Property_Accessors#Dot_notation
31 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/
Property_Accessors#Bracket_notation

29
JavaScript Promise

var promise = Promise.reject(new Error("message"));


promise["catch"](function (error) {
console.error(error);
});

catch then

Promise#thenPromise#catch

var promise = Promise.reject(new Error("message"));


promise.then(undefined, function (error) {
console.error(error);
});

catch Library caught

promise.catch promise["catch"]

IE8 catch

: thenpromise
aPromise.then(...).catch(...) aPromise

then catch promise

promise

var aPromise = new Promise(function (resolve) {


resolve(100);
});
var thenPromise = aPromise.then(function (value) {
console.log(value);
});
var catchPromise = thenPromise.catch(function (error) {
console.error(error);
});
console.log(aPromise !== thenPromise); // => true
console.log(thenPromise !== catchPromise);// => true

30
JavaScript Promise

===
then catch promise

Figure6.

Promise
promise

then promise
then

// 1: promise `then`
var aPromise = new Promise(function (resolve) {
resolve(100);
});
aPromise.then(function (value) {
return value * 2;
});
aPromise.then(function (value) {
return value * 2;
});
aPromise.then(function (value) {
console.log("1: " + value); // => 100
})

// vs

// 2: `then` promise chain


var bPromise = new Promise(function (resolve) {
resolve(100);
});
bPromise.then(function (value) {
return value * 2;

31
JavaScript Promise

}).then(function (value) {
return value * 2;
}).then(function (value) {
console.log("2: " + value); // => 100 * 2 * 2
});

1promisePromise
then then
value 100

2 then
resolve then then then then value
promise return

1 then

then

function badAsyncCall() {
var promise = Promise.resolve();
promise.then(function() {
//
return newVar;
});
return promise;
}

promise.then
then

promise.then promise
2promise chain

then promise

function anAsyncCall() {
var promise = Promise.resolve();
return promise.then(function() {
//
return newVar;
});
}

32
JavaScript Promise

Promise Anti-patterns 32

Promise Promise.all
Promise.race promise
promise

Promise
.then .catch
promise FulFilled Rejected

promise
promiseFulFilled

XHR

XHR

multiple-xhr-callback.js

function getURLCallback(URL, callback) {


var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
callback(null, req.responseText);
} else {
callback(new Error(req.statusText), req.response);
}
};
req.onerror = function () {
callback(new Error(req.statusText));
};
req.send();
}
// <1> JSON
function jsonParse(callback, error, value) {
if (error) {
callback(error, value);
} else {

32 http://taoofcode.net/promise-anti-patterns/

33
JavaScript Promise

try {
var result = JSON.parse(value);
callback(null, result);
} catch (e) {
callback(e, value);
}
}
}
// <2> XHR
var request = {
comment: function getComment(callback) {
return getURLCallback('http://azu.github.io/promises-book/json/comment.json', jsonParse.bind(null,
callback));
},
people: function getPeople(callback) {
return getURLCallback('http://azu.github.io/promises-book/json/people.json', jsonParse.bind(null,
callback));
}
};
// <3> XHRcallback
function allRequest(requests, callback, results) {
if (requests.length === 0) {
return callback(null, results);
}
var req = requests.shift();
req(function (error, value) {
if (error) {
callback(error, value);
} else {
results.push(value);
allRequest(requests, callback, results);
}
});
}
function main(callback) {
allRequest([request.comment, request.people], callback, []);
}
//
main(function(error, results){
if(error){
return console.error(error);
}
console.log(results);
});

34
JavaScript Promise

JSON.parse
jsonParse
XHR allRequest
request
callback(error,value)

jsonParse bind
Partial Function

jsonParse.bind(null, callback);
//
function bindJSONParse(error, value){
jsonParse(callback, error, value);
}


request

Promise#then

Promise#then
Promise.all
.then

.then

multiple-xhr.js

function getURL(URL) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {

35
JavaScript Promise

reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.send();
});
}
var request = {
comment: function getComment() {
return getURL('http://azu.github.io/promises-book/json/comment.json').then(JSON.parse);
},
people: function getPeople() {
return getURL('http://azu.github.io/promises-book/json/people.json').then(JSON.parse);
}
};
function main() {
function recordValue(results, value) {
results.push(value);
return results;
}
// []
var pushValue = recordValue.bind(null, []);
return request.comment().then(pushValue).then(request.people).then(pushValue);
}
//
main().then(function (value) {
console.log(value);
}).catch(function(error){
console.error(error);
});

JSON.parse
main() promise
promise

main then

Promise Promise.all
Promise.race

36
JavaScript Promise

Promise.all
Promise.all promisepromise
resolvereject .then

XHR Promise.all

getURL promiseXHR
Promise.all XHRpromiseXHR
FulFilledRejected .then

promise-all-xhr.js

function getURL(URL) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.send();
});
}
var request = {
comment: function getComment() {
return getURL('http://azu.github.io/promises-book/json/comment.json').then(JSON.parse);
},
people: function getPeople() {
return getURL('http://azu.github.io/promises-book/json/people.json').then(JSON.parse);
}
};
function main() {
return Promise.all([request.comment(), request.people()]);
}
//
main().then(function (value) {
console.log(value);

37
JavaScript Promise

}).catch(function(error){
console.log(error);
});

Promise.all

main
Promise.all promise

Promise.all([request.comment(), request.people()]);

request.comment() request.people()
promiseresolvereject Promise.all promise

.then promise
[comment, people]

main().then(function (results) {
console.log(results); // [comment, people]
});

Promise.all promise

promise-all-timer.js

// `delay`resolve
function timerPromisefy(delay) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(delay);
}, delay);
});
}
var startDate = Date.now();
// promiseresolve
Promise.all([
timerPromisefy(1),
timerPromisefy(32),
timerPromisefy(64),
timerPromisefy(128)

38
JavaScript Promise

]).then(function (values) {
console.log(Date.now() - startDate + 'ms');
// 128ms
console.log(values); // [1,32,64,128]
});

timerPromisefy promise
FulFilled timerPromisefy

Promise.all promise

var promises = [
timerPromisefy(1),
timerPromisefy(32),
timerPromisefy(64),
timerPromisefy(128)
];

1, 32, 64, 128 mspromise resolve

promisepromiseresolve
128ms Promise.all 128ms

Promise.all promise

promise 1ms 32ms


64ms 128ms 225ms

Promise
4Promise

Promise.race
Promise.all promise Promise.race

Promise.allpromise

Promise.all promise FulFilled Rejected


Promise.race promise
FulFilled Rejected

39
JavaScript Promise

Promise.all Promise.race

promise-race-timer.js

// `delay`resolve
function timerPromisefy(delay) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(delay);
}, delay);
});
}
// promiseresolvereject
Promise.race([
timerPromisefy(1),
timerPromisefy(32),
timerPromisefy(64),
timerPromisefy(128)
]).then(function (value) {
console.log(value); // => 1
});

4promisepromise1ms32ms64ms
128msFulFilled1ms .then
promise resolve(1)
value 1 1

promiseFulFilled
promise

promise-race-other.js

var winnerPromise = new Promise(function (resolve) {


setTimeout(function () {
console.log('this is winner');
resolve('this is winner');
}, 4);
});
var loserPromise = new Promise(function (resolve) {
setTimeout(function () {
console.log('this is loser');
resolve('this is loser');
}, 1000);
});
// promiseresolve
Promise.race([winnerPromise, loserPromise]).then(function (value) {

40
JavaScript Promise

console.log(value); // => 'this is winner'
});

console.log

winnterloser promise setTimeout


console.log

Promise.race promiseFulfilled
promise

ES6 Promises promise


promiseresolve or reject
Promise
promise

then or catch?
.catch promise.then(undefined, onRejected)

.catch .then

.then
catch

onRejected

then-throw-error.js

function throwError(value) {
//
throw new Error(value);
}
// <1> onRejected
function badMain(onRejected) {
return Promise.resolve(42).then(throwError, onRejected);
}
// <2> onRejected
function goodMain(onRejected) {
return Promise.resolve(42).then(throwError).catch(onRejected);
}
//
badMain(function(){

41
JavaScript Promise

console.log("BAD");
});
goodMain(function(){
console.log("GOOD");
});

badMain
goodMain

badMain .then
onFulfilled
throwError

throwError onRejected
"BAD"

goodMain throwError onRejected


throwError .catch

.then onRejectedpromise
promise .then onFulfilled
then catch

.then .catch promise Promise



promise

Figure7.Then Catch flow

then Promise.resolve(42) onFulfilled


then onRejected

42
JavaScript Promise

then catch

.catch .then .then


.catch

Promise.resolve(42).then(throwError).then(null, onRejected);

1. promise.then(onFulfilled, onRejected)
onFulfilled onRejected
2. promise.then(onFulfilled).catch(onRejected)
then .catch
3. .then .catch

badMain

Chapter.3 - Promise
Promise

ES6 Promises
Promise Demo

Promise

Mocha 33 Promise

Node.js


azu/promises-book 34

33 http://mochajs.org/
34 https://github.com/azu/promises-book

43
JavaScript Promise

Mocha
MochaNode.js, Mocha 35
Mocha 36

MochaBDDTDDexportsAssert
Mocha

Mocha3


Node.js
"Promise"

"Promise"

MochanpmMocha

$ npm install -g mocha

AssertNode.js assert

Mocha

basic-test.js

var assert = require('power-assert');


describe('Basic Test', function () {
context('When Callback(high-order function)', function () {
it('should use `done` for test', function (done) {
setTimeout(function () {
assert(true);
done();
}, 0);

35 http://mochajs.org/
36 http://mochajs.org/

44
JavaScript Promise

});
});
context('When promise object', function () {
it('should use `done` for test?', function (done) {
var promise = Promise.resolve(1);
//
promise.then(function (value) {
assert(value === 1);
done();
});
});
});
});

basic-test.js Mocha

$ mocha basic-test.js

Mocha it done done()

Mocha

it("should use `done` for test", function (done) {

setTimeout(function () {
assert(true);
done();
}, 0);
});


done

done Promise
done Promise

it("should use `done` for test?", function (done) {


var promise = Promise.resolve(42);
promise.then(function (value) {

45
JavaScript Promise

assert(value === 42);
done();
});
});

Fulfilled promise
done
Promise.resolve promise promiseFulFilled
.then

: Promise promise

assert

promise

it("should use `done` for test?", function (done) {


var promise = Promise.resolve();
promise.then(function (value) {
assert(false);// => throw AssertionError
done();
});
});

assert

Figure8.

assert throwerror error

Promise .then error Promise


error

46
JavaScript Promise

assert promise assert

it("should use `done` for test?", function (done) {


var promise = Promise.resolve();
promise.then(function (value) {
assert(false);
}).then(done, done);
});

done
.then(done, done);

assert done() assert done(error)

Promise

assert .then(done, done);


Promise

Mocha"Promises"

MochaPromise
MochaPromise

Asynchronous code 37 Promise

Alternately, instead of using the done() callback, you can return a promise.
This is useful if the APIs you are testing return promises instead of taking
callbacks:

Promise done()
promise

mocha-promise-test.js

var assert = require('power-assert');

37 http://mochajs.org/#asynchronous-code

47
JavaScript Promise

describe('Promise Test', function () {
it('should return a promise object', function () {
var promise = Promise.resolve(1);
return promise.then(function (value) {
assert(value === 1);
});
});
});

done MochaPromise

done
promise

assert

it("should be fail", function () {


return Promise.resolve().then(function () {
assert(false);// =>
});
});

.then(done, done);

MochaPromises | Web scratch 38


MochaPromise

MochaPromiseMocha

mayBeRejected()
Rejectedpromise

Error Object

function mayBeRejected(){

38 http://efcl.info/2014/0314/res3708/

48
JavaScript Promise

return Promise.reject(new Error("woo"));
}
it("is bad pattern", function () {
return mayBeRejected().catch(function (error) {
assert(error.message === "woo");
});
});

promise

mayBeRejected() promiseFulFilled

mayBeRejected() promiseRejected
assert Error

promiseRejected onRejected
promise

mayBeRejected() FulFilledpromise

function mayBeRejected(){
return Promise.resolve();
}
it("is bad pattern", function () {
return mayBeRejected().catch(function (error) {
assert(error.message === "woo");
});
});

promiseFulFilled
catch onRejected assert
passed

.catch .then
.then

function failTest() {
throw new Error("Expected promise to be rejected but it was fulfilled");
}
function mayBeRejected(){

49
JavaScript Promise

return Promise.resolve();
}
it("should bad pattern", function () {
return mayBeRejected().then(failTest).catch(function (error) {
assert.deepEqual(error.message === "woo");
});
});

throw
then or catch? failTest
catch

Figure9.Then Catch flow

then catch catch Error AssertionError


onRejectedpromise promise
onFulfilled

Error

promise

FulFilled

Rejected
assert

50
JavaScript Promise

FulfilledRejected

function mayBeRejected() {
return Promise.resolve();
}
it("catch -> then", function () {
// FulFilled
return mayBeRejected().then(failTest, function (error) {
assert(error.message === "woo");
});
});

promiseFulFilled

Figure10.Promise onRejected test

then or catch?
.then(onFulfilled, onRejected)
then catch

Promise
.then(failTest, onRejected) promise

51
JavaScript Promise

MochaPromise

then catch

then or catch?

then

AssertionError

.then(onFulfilled, onRejected) promise


FulfilledRejected

Rejected

promise.then(failTest, function(error){
// asserterror
});

helperPromise

controllable tests

promise

Fulfilled

Rejected Fail

assertion Fail

Rejected

Fulfilled Fail

assertion Fail

Fail

52
JavaScript Promise

Fulfilled or Rejected

assertion

.then Rejected

promise.then(failTest, function(error){
// asserterror
assert(error instanceof Error);
});

promise Fulfilled or Rejected

.then

helperpromise

azu/promise-test-helper 39
Promise

shouldRejected helper .then


onRejected

shouldRejected-test.js

var assert = require('power-assert');


function shouldRejected(promise) {
return {
'catch': function (fn) {
return promise.then(function () {
throw new Error('Expected promise to be rejected but it was fulfilled');
}, function (reason) {
fn.call(promise, reason);
});

39 https://github.com/azu/promise-test-helper

53
JavaScript Promise

}
};
}
it('should be rejected', function () {
var promise = Promise.reject(new Error('human error'));
return shouldRejected(promise).catch(function (error) {
assert(error.message === 'human error');
});
});

shouldRejected promise catch

catch onRejected catch


assertion

shouldRejected promise

1. promise shouldRejected

2. catch onRejected

3. onRejectedassertion

shouldRejected Fulfilled throw

promise.then(failTest, function(error){
assert(error.message === 'human error');
});
// ==
shouldRejected(promise).catch(function (error) {
assert(error.message === 'human error');
});

shouldRejected helper

54
JavaScript Promise

Figure11.Promise onRejected test

promiseFulfilled
shouldFulfilled helper

shouldFulfilled-test.js

var assert = require('power-assert');


function shouldFulfilled(promise) {
return {
'then': function (fn) {
return promise.then(function (value) {
fn.call(promise, value);
}, function (reason) {
throw reason;
});
}
};
}
it('should be fulfilled', function () {
var promise = Promise.resolve('value');
return shouldFulfilled(promise).then(function (value) {
assert(value === 'value');
});
});

55
JavaScript Promise

shouldRejected-test.js catch
then promise.then

Promise
helper

shouldFulfilled shouldRejected

azu/promise-test-helper 40

helper MochaPromise done


Promis done

CoffeeScript 41 CoffeeScript return


done

Promise

Chapter.4 - Advanced
Promise
Promise

PromiseLibrary
Promise
Promise

ES6 Promises

40 https://github.com/azu/promise-test-helper
41 http://coffeescript.org/

56
JavaScript Promise

Promise
Promises/A+

Promises/A+ ES6 Promises Promise then

Promises/A+ then
Promise.all catch

Promises/A+ Promise#then
all catch

then Thenable
Promise.resolve ES6 Promisepromise

ES6 Promise promise catch


Promise.all

Polyfill
Promise

Polyfill
Promises/A+

Promise

Polyfill

PolyfillIE10Promise
Promise

PolyfillPromise

jakearchibald/es6-promise 42
ES6 Promises Polyfill RSVP.js 43 Promises/A+
RSVP.js Promises API

42 https://github.com/jakearchibald/es6-promise
43 https://github.com/tildeio/rsvp.js

57
JavaScript Promise

yahoo/ypromise 44
YUI 45 Promise Polyfill ES6 Promises
ypromise Polyfill
getify/native-promise-only 46
ES6 Promisespolyfill ES6 Promises
Promise
Promise

Promise

PromisePromise

Promise

kriskowal/q 47
Q Promises Deferreds 2009
Node.jsIO API Q-IO 48
petkaantonov/bluebird 49
Promise promise
promise

Q Bluebird API reference

API Reference kriskowal/q Wiki 50

QQDeferredjQueryDeferred
Coming from jQuery 51

bluebird/API.md at master petkaantonov/bluebird 52

44 https://github.com/yahoo/ypromise
45 http://yuilibrary.com/
46 https://github.com/getify/native-promise-only/
47 https://github.com/kriskowal/q
48 https://github.com/kriskowal/q-io
49 https://github.com/petkaantonov/bluebird
50 https://github.com/kriskowal/q/wiki/API-Reference
51 https://github.com/kriskowal/q/wiki/Coming-from-jQuery
52 https://github.com/petkaantonov/bluebird/blob/master/API.md

58
JavaScript Promise

BluebirdPromise
Promise 53

Promise Polyfill

Promise

Promise Promises/A+ ES6 Promises

Promise

Promise.resolveThenable
Promise.resolve Promise.resolve
thenablepromise

thenablepromise

Web Notificationsthenable
API Web Notifications 54

Web Notifications API

Web Notifications - WebAPI | MDN 55


Can I use Web Notifications 56

Web Notifications API new Notification

new Notification("Hi!");

53 https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns
54 https://developer.mozilla.org/ja/docs/Web/API/notification
55 https://developer.mozilla.org/zh-TW/docs/WebAPI/Using_Web_Notifications
56 http://caniuse.com/notifications

59
JavaScript Promise

new Notification

Figure12.Notification

Notification
Notification.permission ("granted")
("denied")

NotificationFirefox

Notification.permission

Notification.requestPermission() Notification
status

Notification.requestPermission(function (status) {
// status "granted" "denied"
console.log(status);
});


new Notification

60
JavaScript Promise

("granted")
new Notification
("denied")

Promise
promise Fulfilled Rejected

resolve() == ("granted")
onFulfilled
reject() == ("denied")
onRejected

Promise

Web Notification wrapper


Web Notification API

notification-callback.js

function notifyMessage(message, options, callback) {


if (Notification && Notification.permission === 'granted') {
var notification = new Notification(message, options);
callback(null, notification);
} else if (Notification.requestPermission) {
Notification.requestPermission(function (status) {
if (Notification.permission !== status) {
Notification.permission = status;
}
if (status === 'granted') {
var notification = new Notification(message, options);
callback(null, notification);
} else {

61
JavaScript Promise

callback(new Error('user denied'));
}
});
} else {
callback(new Error('doesn\'t support Notification API'));
}
}
//
// `Notification` option
notifyMessage("Hi!", {}, function (error, notification) {
if(error){
return console.error(error);
}
console.log(notification);//
});

error
notification

errornotification

function callback(error, notification){

Promise

Web Notification as Promise

notifyMessage promise
notifyMessageAsPromise

notification-as-promise.js

function notifyMessage(message, options, callback) {


if (Notification && Notification.permission === 'granted') {
var notification = new Notification(message, options);
callback(null, notification);
} else if (Notification.requestPermission) {
Notification.requestPermission(function (status) {
if (Notification.permission !== status) {
Notification.permission = status;
}
if (status === 'granted') {
var notification = new Notification(message, options);

62
JavaScript Promise

callback(null, notification);
} else {
callback(new Error('user denied'));
}
});
} else {
callback(new Error('doesn\'t support Notification API'));
}
}
function notifyMessageAsPromise(message, options) {
return new Promise(function (resolve, reject) {
notifyMessage(message, options, function (error, notification) {
if (error) {
reject(error);
} else {
resolve(notification);
}
});
});
}
//
notifyMessageAsPromise("Hi!").then(function (notification) {
console.log(notification);//
}).catch(function(error){
console.error(error);
});

"Hi!"

.then
.catch

Web Notifications API



.then

.then

.catch

.catch

63
JavaScript Promise

Web Notifications API



notification-as-promise.js
Promise

notification-as-promise.jsPromise

Promise
Promise
Promise
Promise
Promise
localForage 57
Promise

Thenable

notification-as-promise.js Promise

Thenable Promise

Web Notifications As Thenable


thenable .then
notification-callback.js thenable

notification-thenable.js

function notifyMessage(message, options, callback) {


if (Notification && Notification.permission === 'granted') {
var notification = new Notification(message, options);
callback(null, notification);
} else if (Notification.requestPermission) {
Notification.requestPermission(function (status) {
if (Notification.permission !== status) {

57 https://github.com/mozilla/localForage

64
JavaScript Promise

Notification.permission = status;
}
if (status === 'granted') {
var notification = new Notification(message, options);
callback(null, notification);
} else {
callback(new Error('user denied'));
}
});
} else {
callback(new Error('doesn\'t support Notification API'));
}
}
// `thenable`
function notifyMessageAsThenable(message, options) {
return {
'then': function (resolve, reject) {
notifyMessage(message, options, function (error, notification) {
if (error) {
reject(error);
} else {
resolve(notification);
}
});
}
};
}
//
Promise.resolve(notifyMessageAsThenable("message")).then(function (notification) {
console.log(notification);//
}).catch(function(error){
console.error(error);
});

notification-thenable.js notifyMessageAsThenable
then

then new Promise(function (resolve, reject){})


resolve reject

then notification-as-promise.js notifyMessageAsPromise

Promise.resolve(thenable) thenable promise


Promise

65
JavaScript Promise

Promise.resolve(notifyMessageAsThenable("message")).then(function (notification) {
console.log(notification);//
}).catch(function(error){
console.error(error);
});

Thenablenotification-thenable.js Promise notification-as-promise.js

notification-thenable.js notification-as-promise.js

Promise

Promise.resolve(thenable) Promise

Promise Promise.resolve(thenable)

ThenablePromise

Thenable Promise.resolve(thenable)
Thenablepromise

Callback Thenable Promise

ThenablePromiseAPI

Thenable Promise PromiseThenable


ThenablePromise

Promise.resolve(thenable) Thenable
APIAPI
Thenable


API

Node.jsCore module
PromiseGenerator

66
JavaScript Promise

Promise
PromisepromiseAPI

Thenable

Thenable

Promise

QPromiseQ promise ES6 Promises promise


Q promise promise.finally(callback) promise.nodeify(callback)

ES6 PromisespromiseQ promiseThenable

thenablepromiseQ promise

var Q = require("Q");
// ES6promise
var promise = new Promise(function(resolve){
resolve(1);
});
// Q promise
Q(promise).then(function(value){
console.log(value);
}).finally(function(){
console.log("finally");
});

Q promise finally
promise then Thenable
Q(thenable) ThenableQ promise

Promise.resolve(thenable)

Promisepromise
Thenablenative Promisepromise

Thenable
ThenableThenablePromise

67
JavaScript Promise

rejectthrow
Promise then try...catch
throw

Promise throw try...catch promise


Rejected

var promise = new Promise(function(resolve, reject){


throw new Error("message");
});
promise.catch(function(error){
console.error(error);// => "message"
});

promise
Rejected reject

var promise = new Promise(function(resolve, reject){


reject(new Error("message"));
});
promise.catch(function(error){
console.error(error);// => "message"
})

throw
reject reject Error

reject

promiseRejected reject
throw

throw

ChromeChrome
break

68
JavaScript Promise

Figure13.Pause On Caught Exceptions

throw break

var promise = new Promise(function(resolve, reject){


throw new Error("message");
});

Promise throw break

thenreject

Promise reject
throw promiseRejected

then reject

var promise = Promise.resolve();


promise.then(function (value) {
setTimeout(function () {
// reject - 2
}, 1000);
// - 1
somethingHardWork();
}).catch(function (error) {
// - 3
});

then reject
promise

Promise
Promise.racedelayXHR

then

69
JavaScript Promise

then return
then catch

returnpromise

promisepromise
then onFulfilledonRejected

var promise = Promise.resolve();


promise.then(function () {
var retPromise = new Promise(function (resolve, reject) {
// resolve or reject onFulfilled or onRejected
});
return retPromise;
}).then(onFulfilled, onRejected);

thenpromise
retPromise Rejectedthen
onRejected then throw reject

var onRejected = console.error.bind(console);


var promise = Promise.resolve();
promise.then(function () {
var retPromise = new Promise(function (resolve, reject) {
reject(new Error("this promise is rejected"));
});
return retPromise;
}).catch(onRejected);

the section called Promise.reject

var onRejected = console.error.bind(console);


var promise = Promise.resolve();
promise.then(function () {
return Promise.reject(new Error("this promise is rejected"));
}).catch(onRejected);

70
JavaScript Promise

reject throw

then reject

reject throw
reject

Promise.racedelay
XHR

DeferredPromise

DeferredPromise

Deferred

PromiseDeferred jQuery.Deferred 58
JSDeferred 59

DeferredPromiseLibrary

jQuery.Deferred 60

DeferredPromise

DeferredPromise

Deferred Promise

Deferred Promise""

58 http://api.jquery.com/category/deferred-object/
59 http://cho45.stfuawsc.com/jsdeferred/
60 http://api.jquery.com/category/deferred-object/

71
JavaScript Promise

Figure14.DeferredPromise

DeferredPromise
DeferredPromise

jQuery.DeferredDeferred
Promise

PromiseDeferred

72
JavaScript Promise

Deferred top on Promise

PromiseDeferred

deferred.js

function Deferred() {
this.promise = new Promise(function (resolve, reject) {
this._resolve = resolve;
this._reject = reject;
}.bind(this));
}
Deferred.prototype.resolve = function (value) {
this._resolve.call(this.promise, value);
};
Deferred.prototype.reject = function (reason) {
this._reject.call(this.promise, reason);
};

Promise getURL Deferred

xhr-deferred.js

function Deferred() {
this.promise = new Promise(function (resolve, reject) {
this._resolve = resolve;
this._reject = reject;
}.bind(this));
}
Deferred.prototype.resolve = function (value) {
this._resolve.call(this.promise, value);
};
Deferred.prototype.reject = function (reason) {
this._reject.call(this.promise, reason);
};
function getURL(URL) {
var deferred = new Deferred();
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
deferred.resolve(req.responseText);
} else {
deferred.reject(new Error(req.statusText));
}

73
JavaScript Promise

};
req.onerror = function () {
deferred.reject(new Error(req.statusText));
};
req.send();
return deferred.promise;
}
//
var URL = "http://httpbin.org/get";
getURL(URL).then(function onFulfilled(value){
console.log(value);
}).catch(console.error.bind(console));

Promisepromise
resolverejectPromise
promise

DeferredPromise

xhr-promise.js

function getURL(URL) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.send();
});
}
//
var URL = "http://httpbin.org/get";
getURL(URL).then(function onFulfilled(value){
console.log(value);
}).catch(console.error.bind(console));

getURL

74
JavaScript Promise

Deferred Promise

Promise

resolve reject

promise

DeferredPromiseDeferred
Promise

Promise resolve reject

new Promise(function (resolve, reject){


// promise
});

Deferreddeferred
resolve reject

var deferred = new Deferred();

// `resolve``reject`

Deferred Promise

PromiseDeferred

Promise
FulFilledRejected
Deferred
Promise

Deferred

75
JavaScript Promise

Promise & Deferred objects in JavaScript Pt.1: Theory and Semantics. 61

Twisted Twisted Intro 62

Promise anti patterns petkaantonov/bluebird Wiki 63

Coming from jQuery kriskowal/q Wiki 64

DeferredPython Twisted 65
JavaScript MochiKit.Async 66 dojo/Deferred 67
Library

Promise.racedelayXHR
2 Promise.race
Promise.race

XHR timeout 68
XHRXHR

Promise

Promise

setTimeout

Promise setTimeout

delayPromise.js

function delayPromise(ms) {
return new Promise(function (resolve) {
setTimeout(resolve, ms);
});
}

61 http://blog.mediumequalsmessage.com/promise-deferred-objects-in-javascript-pt1-theory-and-semantics
62 http://skitazaki.appspot.com/translation/twisted-intro-ja/index.html
63 https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern
64 https://github.com/kriskowal/q/wiki/Coming-from-jQuery
65 https://twistedmatrix.com/trac/
66 http://mochi.github.io/mochikit/doc/html/MochiKit/Async.html
67 http://dojotoolkit.org/reference-guide/1.9/dojo/Deferred.html
68 https://developer.mozilla.org/ja/docs/XMLHttpRequest/Synchronous_and_Asynchronous_Requests

76
JavaScript Promise

delayPromise(ms) onFulfilledpromise
setTimeout

setTimeout(function () {
alert("100ms");
}, 100);
// ==
delayPromise(100).then(function () {
alert("100ms");
});

promise

Promise.race
Promise.race promise

var winnerPromise = new Promise(function (resolve) {


setTimeout(function () {
console.log('this is winner');
resolve('this is winner');
}, 4);
});
var loserPromise = new Promise(function (resolve) {
setTimeout(function () {
console.log('this is loser');
resolve('this is loser');
}, 1000);
});
// promiseresolve
Promise.race([winnerPromise, loserPromise]).then(function (value) {
console.log(value); // => 'this is winner'
});

delayPromise promise Promise.race

simple-timeout-promise.js

function delayPromise(ms) {
return new Promise(function (resolve) {
setTimeout(resolve, ms);
});

77
JavaScript Promise

}
function timeoutPromise(promise, ms) {
var timeout = delayPromise(ms).then(function () {
throw new Error('Operation timed out after ' + ms + ' ms');
});
return Promise.race([promise, timeout]);
}

timeoutPromise(promise, ms)
promise Promise.race
promise

timeoutPromise

function delayPromise(ms) {
return new Promise(function (resolve) {
setTimeout(resolve, ms);
});
}
function timeoutPromise(promise, ms) {
var timeout = delayPromise(ms).then(function () {
throw new Error('Operation timed out after ' + ms + ' ms');
});
return Promise.race([promise, timeout]);
}
//
var taskPromise = new Promise(function(resolve){
//
var delay = Math.random() * 2000;
setTimeout(function(){
resolve(delay + "ms");
}, delay);
});
timeoutPromise(taskPromise, 1000).then(function(value){
console.log("taskPromise : " + value);
}).catch(function(error){
console.log("", error);
});

Error Error
TimeoutError

78
JavaScript Promise

Error

Error ECMAScriptbuild in

stack trace Error


Error TimeoutError

ECMAScript6 class

class MyError extends Error{


// Error
}

TimeoutError error instanceof TimeoutError

TimeoutError.js

function copyOwnFrom(target, source) {


Object.getOwnPropertyNames(source).forEach(function (propName) {
Object.defineProperty(target, propName, Object.getOwnPropertyDescriptor(source, propName));
});
return target;
}
function TimeoutError() {
var superInstance = Error.apply(null, arguments);
copyOwnFrom(this, superInstance);
}
TimeoutError.prototype = Object.create(Error.prototype);
TimeoutError.prototype.constructor = TimeoutError;

TimeoutError Errorprototype

Error throw

var promise = new Promise(function(){


throw TimeoutError("timeout");
});

promise.catch(function(error){
console.log(error instanceof TimeoutError);// true
});

79
JavaScript Promise

TimeoutError
Error

JavaScript
Chapter28.Subclassing Built-ins 69 Error -
JavaScript | MDN 70 Error

XHR
PromiseXHR

XHR XMLHttpRequest abort()

abort() getURL
cancelableXHR XHRpromise
XHR abort

delay-race-cancel.js

function cancelableXHR(URL) {
var req = new XMLHttpRequest();
var promise = new Promise(function (resolve, reject) {
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.onabort = function () {
reject(new Error('abort this request'));
};
req.send();
});
var abort = function () {
// requestabort

69 http://speakingjs.com/es5/ch28.html
70 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error

80
JavaScript Promise

// https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
if (req.readyState !== XMLHttpRequest.UNSENT) {
req.abort();
}
};
return {
promise: promise,
abort: abort
};
}

Promise

1. cancelableXHR XHRpromiseXHR
2. timeoutPromise Promise.race XHRpromisepromise

XHR
a. promise then

a. throw TimeoutError catch
b. catch TimeoutError abort
XHR

delay-race-cancel-play.js

function copyOwnFrom(target, source) {


Object.getOwnPropertyNames(source).forEach(function (propName) {
Object.defineProperty(target, propName, Object.getOwnPropertyDescriptor(source, propName));
});
return target;
}
function TimeoutError() {
var superInstance = Error.apply(null, arguments);
copyOwnFrom(this, superInstance);
}
TimeoutError.prototype = Object.create(Error.prototype);
TimeoutError.prototype.constructor = TimeoutError;
function delayPromise(ms) {
return new Promise(function (resolve) {

81
JavaScript Promise

setTimeout(resolve, ms);
});
}
function timeoutPromise(promise, ms) {
var timeout = delayPromise(ms).then(function () {
return Promise.reject(new TimeoutError('Operation timed out after ' + ms + ' ms'));
});
return Promise.race([promise, timeout]);
}
function cancelableXHR(URL) {
var req = new XMLHttpRequest();
var promise = new Promise(function (resolve, reject) {
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.onabort = function () {
reject(new Error('abort this request'));
};
req.send();
});
var abort = function () {
// requestabort
// https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
if (req.readyState !== XMLHttpRequest.UNSENT) {
req.abort();
}
};
return {
promise: promise,
abort: abort
};
}
var object = cancelableXHR('http://httpbin.org/get');
// main
timeoutPromise(object.promise, 1000).then(function (contents) {
console.log('Contents', contents);
}).catch(function (error) {
if (error instanceof TimeoutError) {

82
JavaScript Promise

object.abort();
return console.log(error);
}
console.log('XHR Error :', error);
});

promise

promise
cancelableXHR promise

promise
cancelableXHR req
abort

promise abort
promise

XHRpromise
promiseXHR

AMD,CommonJS,ES6 module etc..


cancelableXHR Node.js

cancelableXHR.js

"use strict";
var requestMap = {};
function createXHRPromise(URL) {
var req = new XMLHttpRequest();
var promise = new Promise(function (resolve, reject) {
req.open('GET', URL, true);

83
JavaScript Promise

req.onreadystatechange = function () {
if (req.readyState === XMLHttpRequest.DONE) {
delete requestMap[URL];
}
};
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.onabort = function () {
reject(new Error('abort this req'));
};
req.send();
});
requestMap[URL] = {
promise: promise,
request: req
};
return promise;
}

function abortPromise(promise) {
if (typeof promise === "undefined") {
return;
}
var request;
Object.keys(requestMap).some(function (URL) {
if (requestMap[URL].promise === promise) {
request = requestMap[URL].request;
return true;
}
});
if (request != null && request.readyState !== XMLHttpRequest.UNSENT) {
request.abort();
}
}
module.exports.createXHRPromise = createXHRPromise;
module.exports.abortPromise = abortPromise;

84
JavaScript Promise

createXHRPromise XHRpromise
XHR abort promise
abortPromise(promise)

var cancelableXHR = require("./cancelableXHR");

var xhrPromise = cancelableXHR.createXHRPromise('http://httpbin.org/get');


xhrPromise.catch(function (error) {
// abort
});
cancelableXHR.abortPromise(xhrPromise);

XHRpromise
1promise

delayPromise

delayPromisePromise.race

XHR promise

promise

Promise

JavaScript

Promise.prototype.done
Promise done then

Promise.prototype.done then
promise

ES6 PromisesPromises/A+ Promise.prototype.done

Promise.prototype.done

85
JavaScript Promise

done

done done

promise-done-example.js

if (typeof Promise.prototype.done === 'undefined') {


Promise.prototype.done = function (onFulfilled, onRejected) {
this.then(onFulfilled, onRejected).catch(function (error) {
setTimeout(function () {
throw error;
}, 0);
});
};
}
var promise = Promise.resolve();
promise.done(function () {
JSON.parse('this is not json'); // => SyntaxError: JSON.parse
});
// =>

promise Promise.prototype.done

then done

then

var promise = Promise.resolve();


promise.then(function () {
JSON.parse("this is not json");
}).catch(function (error) {
console.error(error);// => "SyntaxError: JSON.parse"
});

done promise

done catch

done

PromiseError Handling

86
JavaScript Promise

done promise

Promise done

PromisePromise

Promise
human error

then or catch?

promise

json-promise.js

function JSONPromise(value) {
return new Promise(function (resolve) {
resolve(JSON.parse(value));
});
}

JSON.parse JSON.parse promise

Promise JSON.parse
catch

function JSONPromise(value) {
return new Promise(function (resolve) {
resolve(JSON.parse(value));
});
}
//
var string = "json";
JSONPromise(string).then(function (object) {
console.log(object);
}).catch(function(error){
// => JSON.parse
console.error(error);

87
JavaScript Promise

});

promise

catch

var string = "json";


JSONPromise(string).then(function (object) {
console.log(object);
});


JSON.parse
Syntax Error

typo

var string = "{}";


JSONPromise(string).then(function (object) {
conosle.log(object);
});

conosle
console conosle

ReferenceError: conosle is not defined

Promisetry-catch
catch

unhandled rejection Rejected

unhandled rejectionPromise
ypromise 71 unhandled rejection

Promise rejected but no error handlers were registered to


it

71 https://github.com/yahoo/ypromise

88
JavaScript Promise

Bluebird 72 ReferenceError

"Possibly unhandled ReferenceError. conosle is not


defined

Native PromiseGC-based
unhandled rejection tracking

promiseunhandled
rejection

Firefox 73 Chrome 74 Promise

done

Promise done

Promise done Promise.prototype.done


Promiseprototype

promise-prototype-done.js

"use strict";
if (typeof Promise.prototype.done === "undefined") {
Promise.prototype.done = function (onFulfilled, onRejected) {
this.then(onFulfilled, onRejected).catch(function (error) {
setTimeout(function () {
throw error;
}, 0);
});
};
}

PromisesetTimeout
throw

setTimeout

72 https://github.com/petkaantonov/bluebird
73 https://twitter.com/domenic/status/461154989856264192
74 https://code.google.com/p/v8/issues/detail?id=3093

89
JavaScript Promise

try{
setTimeout(function callback() {
throw new Error("error");
}, 0);
}catch(error){
console.error(error);
}

callback

JavaScript - Yahoo! JAPAN Tech Blog


75

Promise.prototype.done return
done Promise chain
promise

unhandled rejection
done Promise.prototype.done
done Promise ES6
Promises

Promise.prototype.done promisejs.org 76

Q 77 Bluebird 78 prfun 79 Promise done


done then

done

done

75 http://techblog.yahoo.co.jp/programming/javascript_error/
76 https://www.promisejs.org/
77 https://github.com/kriskowal/q/wiki/API-Reference#promisedoneonfulfilled-onrejected-onprogress
78 https://github.com/petkaantonov/bluebird
79 https://github.com/cscott/prfun#promisedoneundefined

90
JavaScript Promise

Promise chain

then or catch? Promise

done
Promise done

ES6 Promises

Promise
Promise

Promises: The Extension Problem (part 4) | getiblog 80


Promise

Promise.prototype

Wrapper/Delegate

Delegate
Chapter28.Subclassing Built-ins 81

Promisemethod chain
Promise then catch DOMjQuery

this

-
82

Promise promise

Promise

80 http://blog.getify.com/promises-part-4/
81 http://speakingjs.com/es5/ch28.html
82 http://taiju.hatenablog.com/entry/20100307/1267962826

91
JavaScript Promise

fs

Node.jsfs 83

fs-method-chain.js

"use strict";
var fs = require("fs");
function File() {
this.lastValue = null;
}
// Static method for File.prototype.read
File.read = function FileRead(filePath) {
var file = new File();
return file.read(filePath);
};
File.prototype.read = function (filePath) {
this.lastValue = fs.readFileSync(filePath, "utf-8");
return this;
};
File.prototype.transform = function (fn) {
this.lastValue = fn.call(this, this.lastValue);
return this;
};
File.prototype.write = function (filePath) {
this.lastValue = fs.writeFileSync(filePath, this.lastValue);
return this;
};
module.exports = File;

read transform write

var File = require("./fs-method-chain");


var inputFilePath = "input.txt",
outputFilePath = "output.txt";
File.read(inputFilePath)
.transform(function (content) {
return ">>" + content;

83 http://nodejs.org/api/fs.html

92
JavaScript Promise

})
.write(outputFilePath);

transform
read >>

Promisefs

Promise

fs-promise-chain.js

"use strict";
var fs = require("fs");
function File() {
this.promise = Promise.resolve();
}
// Static method for File.prototype.read
File.read = function (filePath) {
var file = new File();
return file.read(filePath);
};

File.prototype.then = function (onFulfilled, onRejected) {


this.promise = this.promise.then(onFulfilled, onRejected);
return this;
};
File.prototype["catch"] = function (onRejected) {
this.promise = this.promise.catch(onRejected);
return this;
};
File.prototype.read = function (filePath) {
return this.then(function () {
return fs.readFileSync(filePath, "utf-8");
});
};
File.prototype.transform = function (fn) {
return this.then(fn);
};
File.prototype.write = function (filePath) {
return this.then(function (data) {
return fs.writeFileSync(filePath, data)
});
};

93
JavaScript Promise

module.exports = File;

then catch promise

require

var File = require("./fs-promise-chain");


var inputFilePath = "input.txt",
outputFilePath = "output.txt";
File.read(inputFilePath)
.transform(function (content) {
return ">>" + content;
})
.write(outputFilePath);

File.prototype.then this.promise.then promise


this.promise promise

var File = require("./fs-promise-chain");


File.read(inputFilePath)
.transform(function (content) {
return ">>" + content;
})
.write(outputFilePath);
// =>
promise.then(function read(){
return fs.readFileSync(filePath, "utf-8");
}).then(function transform(content) {
return ">>" + content;
}).then(function write(){
return fs.writeFileSync(filePath, data);
});

promise = promise.then(...) promise


promisechain

promise = addPromiseChain(promise, fn);


promise

94
JavaScript Promise

fs-method-chain.jsPromise

fs-method-chain.js

Promise : Promise
promise

fs-method-chain.js
try-catch

Promise promise then catch


promise catch

fs-promise-chain

var File = require("./fs-promise-chain");


File.read(inputFilePath)
.transform(function (content) {
return ">>" + content;
})
.write(outputFilePath)
.catch(function(error){
console.error(error);
});

fs-method-chain.js
Promise

Promise

Node.js Stream 84

84 http://nodejs.org/api/stream.html

95
JavaScript Promise

Stream 85 this.lastValue
StreamPromise

Streamreadtransformwrite

readableStream.pipe(transformStream).pipe(writableStream);

Promise

Node.jsStreamEvent

Node.jsStream

Node.js Stream API - Block Rockin Codes 86

Stream2 87

Node-v0.12 88

Promise wrapper

fs-method-chain.js Promise

JavaScriptPromise
Promise

ES6 Promises Promise bluebird 89


Promisification 90

promise

var fs = Promise.promisifyAll(require("fs"));

85 http://nodejs.org/api/stream.html
86 http://jxck.hatenablog.com/entry/20111204/1322966453
87 http://www.slideshare.net/shigeki_ohtsu/stream2-kihon
88 http://www.slideshare.net/shigeki_ohtsu/node-v012tng12
89 https://github.com/petkaantonov/bluebird/
90 https://github.com/petkaantonov/bluebird/blob/master/API.md#promisification

96
JavaScript Promise

fs.readFileAsync("myfile.js", "utf8").then(function(contents){
console.log(contents);
}).catch(function(e){
console.error(e.stack);
});

ArrayPromise wrapper

Promisification 91
Array Promise

JavaScriptDOMString Array
map filter

array-promise-chain.js

"use strict";
function ArrayAsPromise(array) {
this.array = array;
this.promise = Promise.resolve();
}
ArrayAsPromise.prototype.then = function (onFulfilled, onRejected) {
this.promise = this.promise.then(onFulfilled, onRejected);
return this;
};
ArrayAsPromise.prototype["catch"] = function (onRejected) {
this.promise = this.promise.catch(onRejected);
return this;
};
Object.getOwnPropertyNames(Array.prototype).forEach(function (methodName) {
// Don't overwrite
if (typeof ArrayAsPromise[methodName] !== "undefined") {
return;
}
var arrayMethod = Array.prototype[methodName];
if (typeof arrayMethod !== "function") {
return;
}
ArrayAsPromise.prototype[methodName] = function () {
var that = this;
var args = arguments;
this.promise = this.promise.then(function () {

91 https://github.com/petkaantonov/bluebird/blob/master/API.md#promisification

97
JavaScript Promise

that.array = Array.prototype[methodName].apply(that.array, args);
return that.array;
});
return this;
};
});

module.exports = ArrayAsPromise;
module.exports.array = function newArrayAsPromise(array) {
return new ArrayAsPromise(array);
};

Array ArrayAsPromise

array-promise-chain-test.js

"use strict";
var assert = require("power-assert");
var ArrayAsPromise = require("../src/promise-chain/array-promise-chain");
describe("array-promise-chain", function () {
function isEven(value) {
return value % 2 === 0;
}

function double(value) {
return value * 2;
}

beforeEach(function () {
this.array = [1, 2, 3, 4, 5];
});
describe("Native array", function () {
it("can method chain", function () {
var result = this.array.filter(isEven).map(double);
assert.deepEqual(result, [4, 8]);
});
});
describe("ArrayAsPromise", function () {
it("can promise chain", function (done) {
var array = new ArrayAsPromise(this.array);
array.filter(isEven).map(double).then(function (value) {
assert.deepEqual(value, [4, 8]);
}).then(done, done);
});
});

98
JavaScript Promise

});

ArrayAsPromise Array
Array ArrayAsPromise

ArrayAsPromise Array.prototype
Array.prototype array.indexOf

APIPromiseAPI API

Promisification 92 Node.jsCore
function(error,result){}
error Promise

Promise
Promise
Promisification

ES6 PromisesCore
Promise

EventPromisePromise

PromisePromise
Promise
Promise

Promisesequence
2 Promise.all promise

92 https://github.com/petkaantonov/bluebird/blob/master/API.md#promisification

99
JavaScript Promise

Promise.all promiseA
B Promise.all

Promise
then

Promise

then

function getURL(URL) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.send();
});
}
var request = {
comment: function getComment() {
return getURL('http://azu.github.io/promises-book/json/comment.json').then(JSON.parse);
},
people: function getPeople() {
return getURL('http://azu.github.io/promises-book/json/people.json').then(JSON.parse);
}
};
function main() {
function recordValue(results, value) {
results.push(value);
return results;
}
// []
var pushValue = recordValue.bind(null, []);
return request.comment().then(pushValue).then(request.people).then(pushValue);

100
JavaScript Promise

}
//
main().then(function (value) {
console.log(value);
}).catch(function(error){
console.error(error);
});

request then

for
for

promise-foreach-xhr.js

function getURL(URL) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.send();
});
}
var request = {
comment: function getComment() {
return getURL('http://azu.github.io/promises-book/json/comment.json').then(JSON.parse);
},
people: function getPeople() {
return getURL('http://azu.github.io/promises-book/json/people.json').then(JSON.parse);
}
};
function main() {
function recordValue(results, value) {
results.push(value);
return results;

101
JavaScript Promise

}
// []
var pushValue = recordValue.bind(null, []);
// promise
var tasks = [request.comment, request.people];
var promise = Promise.resolve();
//
for (var i = 0; i < tasks.length; i++) {
var task = tasks[i];
promise = promise.then(task).then(pushValue);
}
return promise;
}
//
main().then(function (value) {
console.log(value);
}).catch(function(error){
console.error(error);
});

for : thenpromise
Promise Promise#then
promise

promise = promise.then(task).then(pushValue); promise


promise promise

promise

Array.prototype.reduce

Promise chainreduce
Array.prototype.reduce

promise-reduce-xhr.js

function getURL(URL) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));

102
JavaScript Promise

}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.send();
});
}
var request = {
comment: function getComment() {
return getURL('http://azu.github.io/promises-book/json/comment.json').then(JSON.parse);
},
people: function getPeople() {
return getURL('http://azu.github.io/promises-book/json/people.json').then(JSON.parse);
}
};
function main() {
function recordValue(results, value) {
results.push(value);
return results;
}
var pushValue = recordValue.bind(null, []);
var tasks = [request.comment, request.people];
return tasks.reduce(function (promise, task) {
return promise.then(task).then(pushValue);
}, Promise.resolve());
}
//
main().then(function (value) {
console.log(value);
}).catch(function(error){
console.error(error);
});

main for

Array.prototype.reduce
Promise.resolve() promise task request.comment

reduce return promise


then promisefor Promise
chain

Array.prototype.reduce

103
JavaScript Promise

Array.prototype.reduce() - JavaScript | MDN 93

azu / Array.prototype.reduce Dance - Glide 94

reduceforreduce promise
promise = promise.then(task).then(pushValue);

Array.prototype.reduce Promise

sequenceTasks
Task

tasks

var tasks = [request.comment, request.people];


sequenceTasks(tasks);

reduce

promise-sequence.js

function sequenceTasks(tasks) {
function recordValue(results, value) {
results.push(value);
return results;
}
var pushValue = recordValue.bind(null, []);
return tasks.reduce(function (promise, task) {
return promise.then(task).then(pushValue);
}, Promise.resolve());
}

Promise.all

93 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
94 http://glide.so/azu/6919649

104
JavaScript Promise

promisepromise
XHRpromise

sequenceTasks (promise)

sequenceTasks

promise-sequence-xhr.js

function sequenceTasks(tasks) {
function recordValue(results, value) {
results.push(value);
return results;
}
var pushValue = recordValue.bind(null, []);
return tasks.reduce(function (promise, task) {
return promise.then(task).then(pushValue);
}, Promise.resolve());
}
function getURL(URL) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.send();
});
}
var request = {
comment: function getComment() {
return getURL('http://azu.github.io/promises-book/json/comment.json').then(JSON.parse);
},
people: function getPeople() {
return getURL('http://azu.github.io/promises-book/json/people.json').then(JSON.parse);
}
};
function main() {

105
JavaScript Promise

return sequenceTasks([request.comment, request.people]);
}
//
main().then(function (value) {
console.log(value);
}).catch(function(error){
console.error(error);
});

main()

Promise

then
for
reduce

JavaScriptfor forEach
Promise

Promise Promise.all promise

Promise

PromisePromise chain

,Promise then

106
JavaScript Promise

Promises API Reference

Promise#then

promise.then(onFulfilled, onRejected);

then

var promise = new Promise(function(resolve, reject){


resolve("then");
});
promise.then(function (value) {
console.log(value);
}, function (error) {
console.error(error);
});

promiseonFulfilledonRejected
handlerpromise

promiseresolvereject

handlerpromiseonFulfilled

handlerpromiseonRejected

Promise#catch

promise.catch(onRejected);

catch

var promise = new Promise(function(resolve, reject){


resolve("then");
});
promise.then(function (value) {
console.log(value);
}).catch(function (error) {
console.error(error);
});

107
JavaScript Promise

promise.then(undefined, onRejected)

Promise.resolve

Promise.resolve(promise);
Promise.resolve(thenable);
Promise.resolve(object);

Promise.resolve

var taskName = "task 1"


asyncTask(taskName).then(function (value) {
console.log(value);
}).catch(function (error) {
console.error(error);
});
function asyncTask(name){
return Promise.resolve(name).then(function(value){
return "Done! "+ value;
});
}

promise

promise3

promise
promise

thenable
promise then

JavaScriptnull
promise

Promise.reject

Promise.reject(object)

Promise.reject

var failureStub = sinon.stub(xhr, "request").returns(Promise.reject(new Error("bad!")));

108
JavaScript Promise

rejectpromise

Promise.reject Error

Promise.resolvePromise.rejectpromise
promise

var r = Promise.reject(new Error("error"));


console.log(r === Promise.reject(r));// false

Promise.all

Promise.all(promiseArray);

Promise.all

var p1 = Promise.resolve(1),
p2 = Promise.resolve(2),
p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
console.log(results); // [1, 2, 3]
});

promise

promisepromiseresolve
promisepromise

promiserejectPromise.all
rejectpromise

Promise.resolve wrapPaomise.all
promose

Promise.race

Promise.race(promiseArray);

Promise.race

var p1 = Promise.resolve(1),

109
JavaScript Promise

p2 = Promise.resolve(2),
p3 = Promise.resolve(3);
Promise.race([p1, p2, p3]).then(function (value) {
console.log(value); // 1
});

promise

promise promiseresolvereject
promiseresolvereject

Promises
Promise
promise
promise Promise

ES6 Promises
ECMAScript 6th Edition 95 ES6
prefix

Promises/A+
Promises/A+ 96 ES6 Promises ES6 Promises

Thenable
Promise .then

promise chain
then catch promise
ES6 Promises

w3ctag/promises-guide 97
Promises -

95 http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects
96 http://promises-aplus.github.io/promises-spec/
97 https://github.com/w3ctag/promises-guide

110
JavaScript Promise

domenic/promises-unwrapping 98
ES6 Promisesrepo - issue

ECMAScript Language Specification ECMA-262 6th Edition DRAFT 99


ES6 Promises - ES6 Promises

JavaScript Promises: There and back again - HTML5 Rocks 100


Promises - reference

Node.js Promise - 101


Node.jsPromise - thenable

azu 102 (Twitter : @azu_re 103 )

JavaScript

Web Scratch 104 JSer.info 105

liubin https://github.com/liubin

kakauhonnkyou

kaku https://github.com/kaku87

1.1. Promise1.2. Promise 1.3. Promise

honnkyou https://github.com/honnkyou

3.1.

98 https://github.com/domenic/promises-unwrapping
99 http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects
100 http://www.html5rocks.com/en/tutorials/es6/promises/?redirect_from_locale=ja
101 http://d.hatena.ne.jp/jovi0608/20140319/1395199285
102 https://github.com/azu/
103 https://twitter.com/azu_re
104 http://efcl.info/
105 http://jser.info/

111
JavaScript Promise

.pdf 106

Gumroad 0

JavaScript Promise 107

Gumroad

GitHubGitter

Issues azu/promises-book 108

azu/promises-book - Gitter 109

106 https://gumroad.com/l/javascript-promise
107 https://gumroad.com/l/javascript-promise
108 https://github.com/azu/promises-book/issues?state=open
109 https://gitter.im/azu/promises-book

112

You might also like