Professional Documents
Culture Documents
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 Patterns 2
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
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
promise
promise
JavaScriptPromise
6
JavaScript Promise
Promise
ES6 Promises API
Constructor
Instance Method
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 workflow
promise-workflow.js
function asyncFunction() {
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
asyncFunction().then(function (value) {
console.log(value);
}, function (error) {
console.log(error);
});
8
JavaScript Promise
Promise
PromisePromise
"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
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
Promise
Promise
promise
promise
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);
});
reject
11
JavaScript Promise
reject rejectError
200reject reject statusText then
catch
promise
promise
promise
getURL
resolve promiseFulFilled
resolve .then
12
JavaScript Promise
console.log(value);
});
onFulfilled
getURL resolve(req.responseText); promiseresolveFulfilled
onFulfilled
getURL
reject promiseRejected
reject
500
onRejected
getURL reject Error
.catch
getURL(URL).then(onFulfilled, onRejected);
onFulfilled, onRejected
.catch resolvereject
thencatch
13
JavaScript Promise
Promise
Promise
Promise
Promise
Promise
Chapter.2 - Promise
Promise
Promise.resolve
Promise.resolve Promise.reject
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);
});
Thenable
ES6 PromisesThenablepromise
thenablepromisethenable then
Promise then thenable
promisethenable then
thenable jQuery.ajax() 16
thenable
thenablepromise
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
.then
ES6 Promises
https://twitter.com/hirano_y_aa/status/398851806383452160
thenable Promise.cast
PromiseThenableend-
user
4Promise.resolveThenable
ThenablePromise.resolve
Promise.resolve
Fulfilledpromisepromise
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
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
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
promise chain
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");
}
promise chain
21
JavaScript Promise
Figure3.promise-then-catch-flow.js
then (onRejected)
then
onFulfilled
catch
onRejected
22
JavaScript Promise
Rejectedpromise
Promise try-catch
catch
Rejectedpromise
throw promise chain onRejected
4
rejectthrow
Task A onRejected
Task A
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");
}
Task B
taskA throw
onRejected
Rejectedpromise
rejectthrow
promise chain
Task
Task A 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
}
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#then Promise#catch
then or catch?
IE8
polyfill 25
polyfill
Library jakearchibald/es6-promise 26
Promise#catch
25 https://github.com/jakearchibald/es6-promise
26 https://github.com/jakearchibald/es6-promise
28
JavaScript Promise
promise.catch(function (error) {
console.error(error);
});
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
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
catch then
Promise#thenPromise#catch
promise.catch promise["catch"]
IE8 catch
: thenpromise
aPromise.then(...).catch(...) aPromise
promise
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
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
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)
];
promisepromiseresolve
128ms Promise.all 128ms
Promise.all promise
Promise
4Promise
Promise.race
Promise.all promise Promise.race
Promise.allpromise
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
40
JavaScript Promise
console.log(value); // => 'this is winner'
});
console.log
Promise.race promiseFulfilled
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"
.then onRejectedpromise
promise .then onFulfilled
then catch
42
JavaScript Promise
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
AssertNode.js assert
Mocha
basic-test.js
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
setTimeout(function () {
assert(true);
done();
}, 0);
});
done
done Promise
done Promise
45
JavaScript Promise
assert(value === 42);
done();
});
});
Fulfilled promise
done
Promise.resolve promise promiseFulFilled
.then
: Promise promise
assert
promise
assert
Figure8.
46
JavaScript Promise
done
.then(done, done);
Promise
Mocha"Promises"
MochaPromise
MochaPromise
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
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
.then(done, done);
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
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
then or catch?
.then(onFulfilled, onRejected)
then catch
Promise
.then(failTest, onRejected) promise
51
JavaScript Promise
MochaPromise
then catch
then or catch?
then
AssertionError
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);
});
.then
helperpromise
azu/promise-test-helper 39
Promise
shouldRejected-test.js
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
1. promise shouldRejected
2. catch onRejected
3. onRejectedassertion
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
promiseFulfilled
shouldFulfilled helper
shouldFulfilled-test.js
55
JavaScript Promise
shouldRejected-test.js catch
then promise.then
Promise
helper
shouldFulfilled shouldRejected
azu/promise-test-helper 40
Promis 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+ then
Promise.all catch
Promises/A+ Promise#then
all catch
then Thenable
Promise.resolve ES6 Promisepromise
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
QQDeferredjQueryDeferred
Coming from jQuery 51
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
Promise.resolveThenable
Promise.resolve Promise.resolve
thenablepromise
thenablepromise
Web Notificationsthenable
API Web Notifications 54
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
notification-callback.js
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
Promise
notifyMessage promise
notifyMessageAsPromise
notification-as-promise.js
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
.then
.then
.catch
.catch
63
JavaScript Promise
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
notification-thenable.js
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
65
JavaScript Promise
Promise.resolve(notifyMessageAsThenable("message")).then(function (notification) {
console.log(notification);//
}).catch(function(error){
console.error(error);
});
notification-thenable.js notification-as-promise.js
Promise
Promise.resolve(thenable) Promise
Promise Promise.resolve(thenable)
ThenablePromise
Thenable Promise.resolve(thenable)
Thenablepromise
ThenablePromiseAPI
Promise.resolve(thenable) Thenable
APIAPI
Thenable
API
Node.jsCore module
PromiseGenerator
66
JavaScript Promise
Promise
PromisepromiseAPI
Thenable
Thenable
Promise
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
Rejected reject
throw
reject reject Error
reject
promiseRejected reject
throw
throw
ChromeChrome
break
68
JavaScript Promise
throw break
thenreject
Promise reject
throw promiseRejected
then reject
then reject
promise
Promise
Promise.racedelayXHR
then
69
JavaScript Promise
then return
then catch
returnpromise
promisepromise
then onFulfilledonRejected
thenpromise
retPromise Rejectedthen
onRejected then throw reject
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
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);
};
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
Deferreddeferred
resolve reject
// `resolve``reject`
Deferred Promise
PromiseDeferred
Promise
FulFilledRejected
Deferred
Promise
Deferred
75
JavaScript Promise
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
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
ECMAScript6 class
TimeoutError.js
TimeoutError Errorprototype
Error throw
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
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
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
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)
XHRpromise
1promise
delayPromise
delayPromisePromise.race
XHR promise
promise
Promise
JavaScript
Promise.prototype.done
Promise done then
Promise.prototype.done then
promise
Promise.prototype.done
85
JavaScript Promise
done
done done
promise-done-example.js
promise Promise.prototype.done
then done
then
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));
});
}
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
JSON.parse
Syntax Error
typo
conosle
console conosle
Promisetry-catch
catch
unhandled rejectionPromise
ypromise 71 unhandled rejection
71 https://github.com/yahoo/ypromise
88
JavaScript Promise
Bluebird 72 ReferenceError
Native PromiseGC-based
unhandled rejection tracking
promiseunhandled
rejection
done
Promise done
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
Promise.prototype.done return
done Promise chain
promise
unhandled rejection
done Promise.prototype.done
done Promise ES6
Promises
Promise.prototype.done promisejs.org 76
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
done
Promise done
ES6 Promises
Promise
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;
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);
};
93
JavaScript Promise
module.exports = File;
require
94
JavaScript Promise
fs-method-chain.jsPromise
fs-method-chain.js
Promise : Promise
promise
fs-method-chain.js
try-catch
fs-promise-chain
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
Stream2 87
Node-v0.12 88
Promise wrapper
fs-method-chain.js Promise
JavaScriptPromise
Promise
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
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
Array.prototype.reduce
103
JavaScript Promise
reduceforreduce promise
promise = promise.then(task).then(pushValue);
Array.prototype.reduce Promise
sequenceTasks
Task
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
PromisePromise chain
,Promise then
106
JavaScript Promise
Promise#then
promise.then(onFulfilled, onRejected);
then
promiseonFulfilledonRejected
handlerpromise
promiseresolvereject
handlerpromiseonFulfilled
handlerpromiseonRejected
Promise#catch
promise.catch(onRejected);
catch
107
JavaScript Promise
promise.then(undefined, onRejected)
Promise.resolve
Promise.resolve(promise);
Promise.resolve(thenable);
Promise.resolve(object);
Promise.resolve
promise
promise3
promise
promise
thenable
promise then
JavaScriptnull
promise
Promise.reject
Promise.reject(object)
Promise.reject
108
JavaScript Promise
rejectpromise
Promise.reject Error
Promise.resolvePromise.rejectpromise
promise
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
JavaScript
liubin https://github.com/liubin
kakauhonnkyou
kaku https://github.com/kaku87
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
Gumroad
GitHubGitter
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