JavaScript プログラミング講座

 

Promise について

 


■ Promise について

 
ECMAScript 6 世代の機能です。
 
■非同期実行の結果を受け取る
 
非同期実行の結果受け取りには、コールバック関数を使用します。
 
大抵の場合、ライブラリごとに、独自の仕様となります。
 
Promise を使用すると、結果受け取り方法を、統一できます。
 

■Promise の機能一覧

 
■コンストラクタ
 
コンストラクタ説明
Promise()Promise オブジェクトを作成する(実行を開始する)
 
■静的メソッド
 
メソッド説明
Promise.resolve()Promise オブジェクトを作成する(必ず成功する)
Promise.reject()Promise オブジェクトを作成する(必ず失敗する)
Promise.all()複数の実行結果をまとめて取得する
Promise.race()最も先に完了した実行結果を1つ取得する
 
■メソッド
 
メソッド説明
then()実行結果を取得する(成功と失敗)
catch()実行結果を取得する(失敗のみ)
 


 

実行を開始する

 
 


■ Promise オブジェクトを作成する(実行を開始する)

 
new 演算子を使って、Promise コンストラクタをインスタンス化します。
 
Promise オブジェクトを作成した瞬間から、非同期処理は開始されます。
 
new Promise( executor ) :Promise
第01引数 Functionエグゼキューターに相当する関数を指定。
戻り値 Promise新しい Promise オブジェクトが得られる。
 
■第01引数(エグゼキューター)
 
第01引数で指定する関数は、エグゼキューター(実行者)と呼ばれます。
 
この中で、好きな非同期処理を記述します。
 
エグゼキューターは、インスタンス化と同時に、即実行されます。
 
■エグゼキューターの仕様について
 
エグゼキューターの第01~02引数から、コールバック関数が得られます。
 
コールバック関数は、非同期実行に対応しています。
 
後から実行する事もできます。
 
最終的には、どちらか片方を、必ず呼び出す必要があります。
 
引数説明
第01引数実行結果が成功だった場合に呼び出す。
第01引数に、値情報(value)を渡す。
第02引数実行結果が失敗だった場合に呼び出す。
第01引数に、失敗理由情報(reason)を渡す。
 
■戻り値(Promise)
 
実行結果を受け取る方法については、こちらで解説しています。
 
■使用例
 
Promise オブジェクトを作成する

// ------------------------------------------------------------
// エグゼキューター関数
// ------------------------------------------------------------
function ExecutorFunc( resolve , reject ){

	console.log("非同期処理の開始");

	// ------------------------------------------------------------
	// 1 秒後に実行される関数
	// ------------------------------------------------------------
	setTimeout(function(){

		if(1){
			// 成功時
			resolve("成功した");
		}else{
			// 失敗時
			reject("失敗した");
		}

		console.log("非同期処理の完了");

	} , 1000 * 1);

}

// ------------------------------------------------------------
// Promise オブジェクトを作成する(エグゼキューターの実行を開始する)
// ------------------------------------------------------------
var promise = new Promise(ExecutorFunc);

// 出力テスト
console.log(promise);

// ------------------------------------------------------------
// 実行結果を取得する
// ------------------------------------------------------------
promise.then(

	// 成功時に呼び出される
	function onFulfilled(value){
		console.log(value);
	},

	// 失敗時に呼び出される
	function onRejected(reason){
		console.log(reason);
	}

);
 

■ Promise オブジェクトを作成する(必ず成功する)

 
Promise.resolve() メソッドを使用します。
 
Promise.resolve( value ) :Promise
第01引数 *値情報(value)を指定する。
戻り値 Promise新しい Promise オブジェクトが得られる。
 
■戻り値(Promise)
 
実行結果を受け取る方法については、こちらで解説しています。
 
実行結果は、必ず成功となります。
 
第01引数で指定した、値情報(value)が得られます。
 
■使用例
 
必ず成功する Promise オブジェクトを作成する

// ------------------------------------------------------------
// 値情報(value)を用意
// ------------------------------------------------------------
var value = "成功テスト";

// ------------------------------------------------------------
// Promise オブジェクトを作成する(必ず成功する)
// ------------------------------------------------------------
var promise = Promise.resolve(value);

// 出力テスト
console.log(promise);

// ------------------------------------------------------------
// 実行結果を取得する
// ------------------------------------------------------------
promise.then(

	// 成功時に呼び出される
	function onFulfilled(value){
		console.log(value); // "成功テスト"
	},

	// 失敗時に呼び出される
	function onRejected(reason){
		console.log(reason);
	}

);
 

■ Promise オブジェクトを作成する(必ず失敗する)

 
Promise.reject() メソッドを使用します。
 
Promise.reject( reason ) :Promise
第01引数 *失敗理由情報(reason)を指定する。
戻り値 Promise新しい Promise オブジェクトが得られる。
 
■戻り値(Promise)
 
実行結果を受け取る方法については、こちらで解説しています。
 
実行結果は、必ず失敗となります。
 
第01引数で指定した、失敗理由情報(reason)が得られます。
 
■使用例
 
必ず失敗する Promise オブジェクトを作成する

// ------------------------------------------------------------
// 失敗理由情報(reason)を用意
// ------------------------------------------------------------
var reason = new Error("失敗テスト");

// ------------------------------------------------------------
// Promise オブジェクトを作成する(必ず失敗する)
// ------------------------------------------------------------
var promise = Promise.reject(reason);

// 出力テスト
console.log(promise);

// ------------------------------------------------------------
// 実行結果を取得する
// ------------------------------------------------------------
promise.then(

	// 成功時に呼び出される
	function onFulfilled(value){
		console.log(value);
	},

	// 失敗時に呼び出される
	function onRejected(reason){
		console.log(reason); // "失敗テスト"
	}

);
 

■「Thenable なオブジェクト」から、Promise オブジェクトを作成する

 
Promise.resolve() メソッドを使用します。
 
引数に、「Thenable なオブジェクト」を指定します。
 
Promise.resolve( thenable ) :Promise
第01引数 ObjectThenable なオブジェクトを指定する(then メソッドを持つオブジェクト)
戻り値 Promise新しい Promise オブジェクトが得られる。
 
■「Thenable なオブジェクト」とは?
 
then() メソッドを実装しているオブジェクトです。
 
■ then() メソッドの仕様について
 
第01~02引数から、コールバック関数が得られます。
 
コールバック関数は、非同期実行に対応しています。
 
後から実行する事もできます。
 
最終的には、どちらか片方を、必ず呼び出す必要があります。
 
引数説明
第01引数実行結果が成功だった場合に呼び出す。
第01引数に、値情報(value)を渡す。
第02引数実行結果が失敗だった場合に呼び出す。
第01引数に、失敗理由(reason)を渡す。
 
■戻り値(Promise)
 
実行結果を受け取る方法については、こちらで解説しています。
 
■使用例
 
「Thenable なオブジェクト」から、Promise オブジェクトを作成する

// ------------------------------------------------------------
// 「Thenable なオブジェクト」を用意する
// ------------------------------------------------------------
var thenable_obj = {

	// ------------------------------------------------------------
	// then メソッドを実装する
	// ------------------------------------------------------------
	then:function (resolve , reject){

		if(1){
			// 成功時
			resolve("成功した");
		}else{
			// 失敗時
			reject("失敗した");
		}

	}

};

// ------------------------------------------------------------
// 「Thenable なオブジェクト」から、Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise = Promise.resolve(thenable_obj);

// 出力テスト
console.log(promise);
 
「Thenable なオブジェクト」から、Promise オブジェクトを作成し、結果を受け取る

// ------------------------------------------------------------
// ThenableObj コンストラクタ(Thenable の仕様に対応している)
// ------------------------------------------------------------
function ThenableObj(){

	var self = this;

	// ------------------------------------------------------------
	// ローカル変数
	// ------------------------------------------------------------
	var then_arguments = null;
	var receive_obj = null;

	// ------------------------------------------------------------
	// then メソッドを実装する
	// ------------------------------------------------------------
	self.then = function ( resolve , reject ){

		// Arguments オブジェクトを取得
		then_arguments = arguments;

		// 返信を試みる
		receive();
	};

	// ------------------------------------------------------------
	// 返信を試みる関数
	// ------------------------------------------------------------
	function receive(){
		if(!then_arguments) return;
		if(!receive_obj) return;

		// 各コールバック関数を取得
		var resolve = then_arguments[0];
		var reject  = then_arguments[1];

		// 成功時
		if(receive_obj.result){
			if(!resolve) return;
			resolve(receive_obj.value);
		// 失敗時
		}else{
			if(!reject) return;
			reject(receive_obj.reason);
		}
	}

	// ------------------------------------------------------------
	// 非同期処理の実行を開始
	// ------------------------------------------------------------
	(function(){

		// ------------------------------------------------------------
		// 1 秒後に実行される関数
		// ------------------------------------------------------------
		setTimeout(function(){

			// ------------------------------------------------------------
			// 返信オブジェクトを作成
			// ------------------------------------------------------------
			receive_obj = new Object();

			if(1){
				receive_obj.result = true;
				receive_obj.value = "成功した";
			}else{
				receive_obj.result = false;
				receive_obj.reason = new Error("失敗した");
			}

			// ------------------------------------------------------------
			// 返信を試みる
			// ------------------------------------------------------------
			receive();

		} , 1000 * 1);
	})();

}


// ------------------------------------------------------------
// ThenableObj オブジェクトを作成する
// ------------------------------------------------------------
var thenable_obj0 = new ThenableObj();

// ------------------------------------------------------------
// 実行結果を取得する
// ------------------------------------------------------------
thenable_obj0.then(

	// 成功時に呼び出される
	function onFulfilled(value){
		console.log(value);
	},

	// 失敗時に呼び出される
	function onRejected(reason){
		console.log(reason);
	}

);


// ------------------------------------------------------------
// ThenableObj オブジェクトを作成する
// ------------------------------------------------------------
var thenable_obj1 = new ThenableObj();

// ------------------------------------------------------------
// 「Thenable なオブジェクト」から、Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise = Promise.resolve(thenable_obj1);

// ------------------------------------------------------------
// 実行結果を取得する(純粋な Promise なので、この後 Promise チェーンなども利用できる)
// ------------------------------------------------------------
promise.then(

	// 成功時に呼び出される
	function onFulfilled(value){
		console.log(value);
	},

	// 失敗時に呼び出される
	function onRejected(reason){
		console.log(reason);
	}

);
 


 

実行結果を取得する

 
 


■実行結果を取得する(成功と失敗)

 
then() メソッドを使用します。
 
このメソッドは、非同期実行です。
 
結果を受け取るには、引数にコールバック関数を指定します。
 
Promise.then( onFulfilled , onRejected ) :Promise
第01引数 Function成功時に呼び出されるコールバック関数を指定する。
第02引数(略可)Function失敗時に呼び出されるコールバック関数を指定する。
戻り値 Promise新しい Promise オブジェクトが得られる。
 
■第01引数(onFulfilled)
 
成功時に呼び出されるコールバック関数を指定します。
 
コールバック関数の仕様は、以下の通りです。
 
第01引数から、値情報(value)を受け取れます。
 
戻り値から、好きな Promise オブジェクトを返す事もできます。
 
これは、Promise チェーンで使用します。
 
■第02引数(onRejected)
 
失敗時に呼び出されるコールバック関数を指定します。
 
コールバック関数の仕様は、以下の通りです。
 
第01引数から、失敗理由情報(reason)を受け取れます。
 
戻り値から、好きな Promise オブジェクトを返す事もできます。
 
これは、Promise チェーンで使用します。
 
■戻り値(Promise)
 
新しい Promise オブジェクトが得られます。
 
これは、Promise チェーンで使用します。
 
■使用例
 
エグゼキューターの実行結果を取得する

// ------------------------------------------------------------
// エグゼキューター関数
// ------------------------------------------------------------
function ExecutorFunc( resolve , reject ){
	if(1){
		// 成功時
		resolve("成功した");
	}else{
		// 失敗時
		reject("失敗した");
	}
}

// ------------------------------------------------------------
// Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise = new Promise(ExecutorFunc);

// ------------------------------------------------------------
// 成功時に呼び出される関数
// ------------------------------------------------------------
function FulfilledFunc (value){
	console.log(value);
}

// ------------------------------------------------------------
// 失敗時に呼び出される関数
// ------------------------------------------------------------
function RejectedFunc (reason){
	console.log(reason);
}

// ------------------------------------------------------------
// 実行結果を取得する
// ------------------------------------------------------------
promise.then( FulfilledFunc , RejectedFunc);
 
「ロード済みイメージ要素」の作成を開始し、結果を取得する

// ------------------------------------------------------------
// 「ロード済みイメージ要素」を作成する関数
// ------------------------------------------------------------
function ImageElement_CreateAndLoad( url ){

	// ------------------------------------------------------------
	// Promise オブジェクトを作成する
	// ------------------------------------------------------------
	var promise = new Promise(function(resolve,reject){

		// イメージ要素を作成
		var image = new Image();

		// 読み込み成功時に実行されるイベント
		image.onload = function(){
			resolve(image);
		}

		// 読み込み失敗時に実行されるイベント
		image.onerror = function(){
			reject(new Error("Not Found"));
		}

		// URL を指定して、読み込みを開始する
		image.src = url;
	});

	// ------------------------------------------------------------
	// Promise オブジェクトを返す
	// ------------------------------------------------------------
	return promise;
}


// ------------------------------------------------------------
// 「ロード済みイメージ要素」の作成を開始する
// ------------------------------------------------------------
var promise = ImageElement_CreateAndLoad( "http://example.com/graphics/texture_00.png" );

// ------------------------------------------------------------
// 実行結果を取得する
// ------------------------------------------------------------
promise.then(

	// 成功時に呼び出される
	function onFulfilled(value){
		console.log(value);
	},

	// 失敗時に呼び出される
	function onRejected(reason){
		console.log(reason);
	}

);
 

■実行結果を取得する(失敗のみ)

 
catch() メソッドを使用します。
 
このメソッドは、非同期実行です。
 
結果を受け取るには、引数にコールバック関数を指定します。
 
Promise.catch( onRejected ) :Promise
第01引数 Function失敗時に呼び出されるコールバック関数を指定する。
戻り値 Promise新しい Promise オブジェクトが得られる。
 
■第01引数(onRejected)
 
失敗時に呼び出されるコールバック関数を指定します。
 
コールバック関数の仕様は、以下の通りです。
 
第01引数から、失敗理由情報(reason)を受け取れます。
 
戻り値から、好きな Promise オブジェクトを返す事もできます。
 
これは、Promise チェーンで使用します。
 
■戻り値(Promise)
 
新しい Promise オブジェクトが得られます。
 
これは、Promise チェーンで使用します。
 
■使用例
 
エグゼキューターの実行結果を取得する

// ------------------------------------------------------------
// エグゼキューター関数
// ------------------------------------------------------------
function ExecutorFunc( resolve , reject ){
	if(0){
		// 成功時
		resolve("成功した");
	}else{
		// 失敗時
		reject("失敗した");
	}
}

// ------------------------------------------------------------
// Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise = new Promise(ExecutorFunc);

// ------------------------------------------------------------
// 失敗時に呼び出される関数
// ------------------------------------------------------------
function RejectedFunc (reason){
	console.log(reason);
}

// ------------------------------------------------------------
// 実行結果を取得する(失敗のみ)
// ------------------------------------------------------------
promise.catch(RejectedFunc);
 
「ロード済みイメージ要素」の作成を開始し、結果を取得する

// ------------------------------------------------------------
// 「ロード済みイメージ要素」を作成する関数
// ------------------------------------------------------------
function ImageElement_CreateAndLoad( url ){

	// ------------------------------------------------------------
	// Promise オブジェクトを作成する
	// ------------------------------------------------------------
	var promise = new Promise(function(resolve,reject){

		// イメージ要素を作成
		var image = new Image();

		// 読み込み成功時に実行されるイベント
		image.onload = function(){
			resolve(image);
		}

		// 読み込み失敗時に実行されるイベント
		image.onerror = function(){
			reject(new Error("Not Found"));
		}

		// URL を指定して、読み込みを開始する
		image.src = url;
	});

	// ------------------------------------------------------------
	// Promise オブジェクトを返す
	// ------------------------------------------------------------
	return promise;
}


// ------------------------------------------------------------
// 「ロード済みイメージ要素」の作成を開始する
// ------------------------------------------------------------
var promise = ImageElement_CreateAndLoad( "http://example.com/graphics/texture_00.png" );

// ------------------------------------------------------------
// 実行結果を取得する(成功のみ)
// ------------------------------------------------------------
promise = promise.then(function (value){
	console.log(value);
});

// ------------------------------------------------------------
// 実行結果を取得する(失敗のみ)
// ------------------------------------------------------------
promise = promise.catch(function (reason){
	console.log(reason);
});
 

■複数の実行結果をまとめて取得する

 
Promise.all() メソッドを使用します。
 
Promise.all( promiseArray ) :Promise
第01引数 ArrayPromise のリストを指定する。
戻り値 Promise新しい Promise オブジェクトが得られる。
 
■戻り値(Promise)
 
新しい Promise オブジェクトが得られます。
 
結果を受け取るには、さらに then() メソッドを呼び出します。
 
すべての結果は、配列に格納されています。
 
結果の格納順序は、Promise.all() の第01引数の順序と同じです。
 
■非同期処理の並列実行に注意
 
結果を取得したい Promise オブジェクトは、すべて事前に作成しておく必要があります。
 
Promise オブジェクトを作成すると、非同期処理も開始されます。
 
複数同時に作成した場合、非同期処理も同時に実行されています。
 
1つずつ順番に実行したい場合は、Promise チェーンを利用します。
 
■使用例
 
複数の実行結果をまとめて取得する

// ------------------------------------------------------------
// 「指定時間後」に「指定結果」が得られる関数
// ------------------------------------------------------------
function PromiseCreateFunc( value , time ){

	// Promise オブジェクトを作成する
	var promise = new Promise(function(resolve,reject){
		setTimeout(function(){
			resolve(value);
		} , time);
	});

	// Promise オブジェクトを返す
	return promise;
}


// ------------------------------------------------------------
// 複数の Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise0 = PromiseCreateFunc( "aaaaa" , 3000 );
var promise1 = PromiseCreateFunc( "bbbbb" , 1000 );
var promise2 = PromiseCreateFunc( "ccccc" , 2000 );

// ------------------------------------------------------------
// 「複数の実行結果」の取得を開始する
// ------------------------------------------------------------
var promise = Promise.all( [promise0 , promise1 , promise2] );

// ------------------------------------------------------------
// 「複数の実行結果」を取得する
// ------------------------------------------------------------
promise.then(

	// 成功時に呼び出される
	function onFulfilled(value){
		console.log(value); // [ "aaaaa" , "bbbbb" , "ccccc" ]
	},

	// 失敗時に呼び出される
	function onRejected(reason){
		console.log(reason);
	}
);
 

■最も先に完了した実行結果を1つ取得する

 
Promise.race() メソッドを使用します。
 
Promise.race( promiseArray ) :Promise
第01引数 ArrayPromise のリストを指定する。
戻り値 Promise新しい Promise オブジェクトが得られる。
 
■戻り値(Promise)
 
新しい Promise オブジェクトが得られます。
 
結果を受け取るには、さらに then() メソッドを呼び出します。
 
最も先に完了した実行結果を、1つだけ取得できます。
 
複数が完了済みだった場合、Promise.race() の第01引数の昇順で評価されます。
 
■キャンセルについて
 
Promise 自体には、キャンセルに対応する仕様はありません。
 
すべての非同期処理は、最後まで実行されます。
 
■使用例
 
最も先に完了した実行結果を1つ取得する

// ------------------------------------------------------------
// 「指定時間後」に「指定結果」が得られる関数
// ------------------------------------------------------------
function PromiseCreateFunc( value , time ){

	// Promise オブジェクトを作成する
	var promise = new Promise(function(resolve,reject){
		setTimeout(function(){
			resolve(value);
		} , time);
	});

	// Promise オブジェクトを返す
	return promise;
}


// ------------------------------------------------------------
// 複数の Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise0 = PromiseCreateFunc( "aaaaa" , 3000 );
var promise1 = PromiseCreateFunc( "bbbbb" , 1000 );
var promise2 = PromiseCreateFunc( "ccccc" , 2000 );

// ------------------------------------------------------------
// 「最も先に完了した実行結果」の取得を開始する
// ------------------------------------------------------------
var promise = Promise.race( [promise0 , promise1 , promise2] );

// ------------------------------------------------------------
// 「最も先に完了した実行結果」を取得する
// ------------------------------------------------------------
promise.then(

	// 成功時に呼び出される
	function onFulfilled(value){
		console.log(value); // "bbbbb"
	},

	// 失敗時に呼び出される
	function onRejected(reason){
		console.log(reason);
	}
);
 


 

Promise チェーンについて

 


■ Promise のメソッドチェーンについて

 
■対応メソッド
 
以下のメソッドは、メソッドチェーンに対応しています。
 
メソッド説明
then()実行結果を取得する(成功と失敗)
catch()実行結果を取得する(失敗のみ)
 
■メソッドチェーンを利用した場合
 
メソッドチェーンを利用すると、コールバック関数を接続する事ができます。
 
数珠つなぎにして、複数のコールバック関数を連結する事ができます。
 
接続したコールバック関数は、順序通りに実行されます。
 
■使用例
 
複数のコールバック関数を接続し、実行順序を確認する(メソッドチェーン表記)

// ------------------------------------------------------------
// ExecA 関数
// ------------------------------------------------------------
function ExecA( value ){
	console.log("--- ExecA ---");
}

// ------------------------------------------------------------
// ExecB 関数
// ------------------------------------------------------------
function ExecB( value ){
	console.log("--- ExecB ---");
}

// ------------------------------------------------------------
// ExecC 関数
// ------------------------------------------------------------
function ExecC( value ){
	console.log("--- ExecC ---");
}

// ------------------------------------------------------------
// ExecD 関数
// ------------------------------------------------------------
function ExecD( value ){
	console.log("--- ExecD ---");
}

// ------------------------------------------------------------
// Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise = Promise.resolve();

// ------------------------------------------------------------
// メソッドチェーンを使って、コールバック関数を接続する
// ------------------------------------------------------------
promise.then(ExecA).then(ExecB).then(ExecC).then(ExecD);
 
複数のコールバック関数を接続し、実行順序を確認する

// ------------------------------------------------------------
// Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise = Promise.resolve("start");

// ------------------------------------------------------------
// コールバック関数を接続する
// ------------------------------------------------------------
promise = promise.then( function (value){
	console.log("--- ExecA ---");
});

// ------------------------------------------------------------
// コールバック関数を接続する
// ------------------------------------------------------------
promise = promise.then( function (value){
	console.log("--- ExecB ---");
});

// ------------------------------------------------------------
// コールバック関数を接続する
// ------------------------------------------------------------
promise = promise.then( function (value){
	console.log("--- ExecC ---");
});

// ------------------------------------------------------------
// コールバック関数を接続する
// ------------------------------------------------------------
promise = promise.then( function (value){
	console.log("--- ExecD ---");
});
 

■コールバック関数の戻り値と、新しい結果について

 
■チェーン対応メソッドの戻り値について
 
新しい Promise オブジェクトが得られます。
 
新しい Promise オブジェクトから、then() メソッドを呼び出します。
 
第01引数から、次に実行したいコールバック関数を指定できます。
 
登録したコールバック関数からは、新しい結果を受け取れます。
 
■コールバック関数の戻り値について
 
好きな Promise オブジェクトを返す事ができます。
 
ここで返した Promise オブジェクトは、次回の結果となります。
 
■コールバック関数の引数について
 
コールバック関数の第01引数から、今回の結果が得られます。
 
前回のコールバック関数の戻り値が、今回の結果となります。
 
■使用例
 
コールバック関数の戻り値と、新しい結果を確認する(メソッドチェーン表記)

// ------------------------------------------------------------
// ExecA 関数
// ------------------------------------------------------------
function ExecA( value ){
	console.log("--- ExecA ---");

	// 「今回の結果」を取得
	console.log(value); // "start"

	// 「次回の結果」を返す
	var promise = Promise.resolve("aaaaa");
	return promise;
}

// ------------------------------------------------------------
// ExecB 関数
// ------------------------------------------------------------
function ExecB( value ){
	console.log("--- ExecB ---");

	// 「今回の結果」を取得
	console.log(value); // "aaaaa"

	// 「次回の結果」を返す
	var promise = Promise.resolve("bbbbb");
	return promise;
}

// ------------------------------------------------------------
// ExecC 関数
// ------------------------------------------------------------
function ExecC( value ){
	console.log("--- ExecC ---");

	// 「今回の結果」を取得
	console.log(value); // "bbbbb"

	// 「次回の結果」を返す
	var promise = Promise.resolve("ccccc");
	return promise;
}

// ------------------------------------------------------------
// ExecD 関数
// ------------------------------------------------------------
function ExecD( value ){
	console.log("--- ExecD ---");

	// 「今回の結果」を取得
	console.log(value); // "ccccc"
}

// ------------------------------------------------------------
// Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise = Promise.resolve("start");

// ------------------------------------------------------------
// メソッドチェーンを使って、コールバック関数を接続する
// ------------------------------------------------------------
promise.then(ExecA).then(ExecB).then(ExecC).then(ExecD);
 
コールバック関数の戻り値と、新しい結果を確認する

// ------------------------------------------------------------
// Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise = Promise.resolve("start");

// ------------------------------------------------------------
// コールバック関数を接続する
// ------------------------------------------------------------
promise = promise.then( function (value){
	console.log("--- ExecA ---");

	// 「今回の結果」を取得
	console.log(value); // "start"

	// 「次回の結果」を返す
	var promise = Promise.resolve("aaaaa");
	return promise;
});

// ------------------------------------------------------------
// コールバック関数を接続する
// ------------------------------------------------------------
promise = promise.then( function (value){
	console.log("--- ExecB ---");

	// 「今回の結果」を取得
	console.log(value); // "aaaaa"

	// 「次回の結果」を返す
	var promise = Promise.resolve("bbbbb");
	return promise;
});

// ------------------------------------------------------------
// コールバック関数を接続する
// ------------------------------------------------------------
promise = promise.then( function (value){
	console.log("--- ExecC ---");

	// 「今回の結果」を取得
	console.log(value); // "bbbbb"

	// 「次回の結果」を返す
	var promise = Promise.resolve("ccccc");
	return promise;
});

// ------------------------------------------------------------
// コールバック関数を接続する
// ------------------------------------------------------------
promise = promise.then( function (value){
	console.log("--- ExecD ---");

	// 「今回の結果」を取得
	console.log(value); // "ccccc"
});
 

■次回の結果を必ず成功させるには

 
■必ず成功する Promise オブジェクトを作成する
 
Promise.resolve() メソッドを使用します。
 
この Promise オブジェクトを、コールバック関数から返します。
 
この場合、次回の結果は、必ず成功します。
 
■コールバック関数から、任意の値を返した場合
 
任意の値は、自動的に Promise オブジェクトに変換されます。
 
Promise.resolve() メソッドを呼び出した場合と同等です。
 
この場合、次回の結果は、必ず成功します。
 

■次回の結果を必ず失敗させるには

 
■必ず失敗する Promise オブジェクトを作成する
 
Promise.reject() メソッドを使用します。
 
この Promise オブジェクトを、コールバック関数から返します。
 
この場合、次回の結果は、必ず失敗します。
 
■コールバック関数内でエラーが発生した場合
 
コールバック関数内で、エラーを発生させます。
 
この場合、次回の結果は、必ず失敗します。
 
■失敗やエラーを、まとめてキャッチする
 
catch() メソッドを使用します。
 
Promise チェーン内で発生した、失敗やエラーなどを、まとめて捕捉できます。
 
■使用例
 
失敗やエラーを、まとめてキャッチする(メソッドチェーン表記)

// ------------------------------------------------------------
// ExecA 関数
// ------------------------------------------------------------
function ExecA( value ){
	console.log("--- ExecA ---");

	// 「次回の結果」は必ず成功
	var promise = Promise.resolve("aaaaa");
	return promise;
}

// ------------------------------------------------------------
// ExecB 関数
// ------------------------------------------------------------
function ExecB( value ){
	console.log("--- ExecB ---");

	if(0){
		// 「次回の結果」は必ず成功
		var promise = Promise.resolve("bbbbb");
		return promise;
	}else{
		// 「次回の結果」は必ず失敗
		var promise = Promise.reject(new Error("失敗テスト"));
		return promise;
	}
}

// ------------------------------------------------------------
// ExecC 関数
// ------------------------------------------------------------
function ExecC( value ){
	console.log("--- ExecC ---");
}

// ------------------------------------------------------------
// ErrorCatchFunc 関数
// ------------------------------------------------------------
function ErrorCatchFunc( reason ){
	// 失敗理由情報を取得
	console.log(reason);
}

// ------------------------------------------------------------
// Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise = Promise.resolve("start");

// ------------------------------------------------------------
// メソッドチェーンを使って、コールバック関数を接続する
// ------------------------------------------------------------
promise.then(ExecA).then(ExecB).then(ExecC).catch(ErrorCatchFunc);
 
失敗やエラーを、まとめてキャッチする

// ------------------------------------------------------------
// Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise = Promise.resolve("start");

// ------------------------------------------------------------
// 成功コールバック関数を接続する
// ------------------------------------------------------------
promise = promise.then( function (value){
	console.log("--- ExecA ---");

	// 「次回の結果」は必ず成功
	var promise = Promise.resolve("aaaaa");
	return promise;
});

// ------------------------------------------------------------
// 成功コールバック関数を接続する
// ------------------------------------------------------------
promise = promise.then( function (value){
	console.log("--- ExecB ---");

	if(0){
		// 「次回の結果」は必ず成功
		var promise = Promise.resolve("bbbbb");
		return promise;
	}else{
		// 「次回の結果」は必ず失敗
		var promise = Promise.reject(new Error("失敗テスト"));
		return promise;
	}
});

// ------------------------------------------------------------
// 成功コールバック関数を接続する
// ------------------------------------------------------------
promise = promise.then( function (value){
	console.log("--- ExecC ---");
});

// ------------------------------------------------------------
// 失敗コールバック関数を接続する
// ------------------------------------------------------------
promise = promise.catch( function (reason){
	// 失敗理由情報を取得
	console.log(reason);
});
 

■ Promise チェーンの非同期実行について

 
■ Promise の同期実行に注意
 
あたかも非同期動作しそうですが、Promise 自体は同期実行です。
 
setTimeout() のような、遅延実行を行う事はありません。
 
対応可能なキューが貯まっている場合、一度にすべての消化を試みます。
 
この間、ブラウザは応答不能に陥ります。
 
■ Promise を非同期実行化するには?
 
エグゼキューター付きの Promise オブジェクトを生成します。
 
エグゼキューター関数内にて、好きな非同期 API を利用します。
 
非同期 API を利用しなかった場合、Promise は同期実行となります。
 
この Promise オブジェクトを、コールバック関数から返します。
 
■使用例
 
Promise チェーンを遅延実行する

// ------------------------------------------------------------
// 「指定時間後」に「指定結果」が得られる関数
// ------------------------------------------------------------
function PromiseCreateFunc( value , time ){

	// Promise オブジェクトを作成する
	var promise = new Promise(function(resolve,reject){
		setTimeout(function(){
			resolve(value);
		} , time);
	});

	// Promise オブジェクトを返す
	return promise;
}


// ------------------------------------------------------------
// Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise = Promise.resolve(0);

(function(){

	var i = 0;
	var num = 10000;
	for(i=0;i < num;i++){

		// ------------------------------------------------------------
		// コールバック関数を接続する
		// ------------------------------------------------------------
		promise = promise.then( function (value){
			if((value % 100) == 0) console.log(value);

			// 新しい Promise オブジェクトを作成する(非同期動作)
			var promise = PromiseCreateFunc( (value + 1) , 1 );
			return promise;
		});
	}
})();

// ------------------------------------------------------------
// コールバック関数を接続する(最後に動作)
// ------------------------------------------------------------
promise = promise.then( function (){
	console.timeEnd("test");
});

console.time("test");
 

■複数の Promise を1つずつ順番に実行する

 
■非同期処理の開始タイミングについて
 
Promise オブジェクトを作成すると、非同期処理も開始されます。
 
よって事前に、Promise オブジェクトを生成しておく事はできません。
 
■直列的に1つずつ実行するには?
 
コールバック関数内にて、Promise オブジェクトを作成します。
 
この Promise オブジェクトを、コールバック関数から返します。
 
■使用例
 
Promise チェーンを使って、1つずつ順番に実行する

// ------------------------------------------------------------
// 「指定時間後」に「指定結果」が得られる関数
// ------------------------------------------------------------
function PromiseCreateFunc( value , time ){

	// Promise オブジェクトを作成する
	var promise = new Promise(function(resolve,reject){
		setTimeout(function(){
			resolve(value);
		} , time);
	});

	// Promise オブジェクトを返す
	return promise;
}


// ------------------------------------------------------------
// Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise = Promise.resolve();

// ------------------------------------------------------------
// 成功時に呼び出される関数を接続
// ------------------------------------------------------------
promise = promise.then( function (value){
	// 「非同期処理」を開始する
	var promise = PromiseCreateFunc( "aaaaa" , 1000 );
	// 「次回の結果」を返す
	return promise;
});

// ------------------------------------------------------------
// 成功時に呼び出される関数を接続
// ------------------------------------------------------------
promise = promise.then( function (value){
	// 「今回の結果」を取得
	console.log(value); // "aaaaa"
	// 「非同期処理」を開始する
	var promise = PromiseCreateFunc( "bbbbb" , 1000 );
	// 「次回の結果」を返す
	return promise;
});

// ------------------------------------------------------------
// 成功時に呼び出される関数を接続
// ------------------------------------------------------------
promise = promise.then( function (value){
	// 「今回の結果」を取得
	console.log(value); // "bbbbb"
	// 「非同期処理」を開始する
	var promise = PromiseCreateFunc( "ccccc" , 1000 );
	// 「次回の結果」を返す
	return promise;
});

// ------------------------------------------------------------
// 成功時に呼び出される関数を接続
// ------------------------------------------------------------
promise = promise.then( function (value){
	// 「今回の結果」を取得
	console.log(value); // "ccccc"
});

// ------------------------------------------------------------
// 失敗時に呼び出される関数を接続(Promise チェーン内で発生したエラーをキャッチ)
// ------------------------------------------------------------
promise = promise.catch( function (reason){
	console.log(reason);
});
 
Promise チェーンに割り込んで、コールバック関数を繰り返し実行する

// ------------------------------------------------------------
// 「ロード済みイメージ要素」を作成する関数
// ------------------------------------------------------------
function ImageElement_CreateAndLoad( url ){

	// ------------------------------------------------------------
	// Promise オブジェクトを作成する
	// ------------------------------------------------------------
	var promise = new Promise(function(resolve,reject){

		// イメージ要素を作成
		var image = new Image();

		// 読み込み成功時に実行されるイベント
		image.onload = function(){
			resolve(image);
		}

		// 読み込み失敗時に実行されるイベント
		image.onerror = function(){
			reject(new Error("Not Found"));
		}

		// URL を指定して、読み込みを開始する
		image.src = url;
	});

	// ------------------------------------------------------------
	// Promise オブジェクトを返す
	// ------------------------------------------------------------
	return promise;
}


// ------------------------------------------------------------
// Promise オブジェクトを作成する
// ------------------------------------------------------------
var promise = Promise.resolve();

(function(){

	// ------------------------------------------------------------
	// URL リスト
	// ------------------------------------------------------------
	var url_list = [
		"http://example.com/graphics/texture_00.png",
		"http://example.com/graphics/texture_01.png",
		"http://example.com/graphics/texture_02.png",
		"http://example.com/graphics/texture_03.png",
		"http://example.com/graphics/texture_04.png"
	];

	// 値情報リスト
	var value_list = new Array();

	var i = 0;
	var num = url_list.length;

	// ------------------------------------------------------------
	// 成功時に呼び出される関数を接続(繰り返し実行)
	// ------------------------------------------------------------
	promise = promise.then(function execute(value){

		// 値情報リストに追加
		if(value) value_list.push(value);

		// 繰り返し終了
		if(i >= num) return value_list;

		// ------------------------------------------------------------
		// 「ロード済みイメージ要素」の作成を開始する
		// ------------------------------------------------------------
		var promise = ImageElement_CreateAndLoad( url_list[i] );
		i += 1;

		// ------------------------------------------------------------
		// 成功時に呼び出される関数を接続(Promise チェーンに割り込む)
		// ------------------------------------------------------------
		promise = promise.then(execute);
		return promise;
	});

})();

// ------------------------------------------------------------
// 成功時に呼び出される関数を接続(最後まで完了した場合)
// ------------------------------------------------------------
promise = promise.then( function (value){
	console.log(value);
});

// ------------------------------------------------------------
// 失敗時に呼び出される関数を接続(Promise チェーン内で発生したエラーをキャッチ)
// ------------------------------------------------------------
promise = promise.catch( function (reason){
	console.log(reason);
});