トッカンソフトウェア

Promise

今回はPromiseをやります。


JavaScriptは通常であれば上から順に実行されます。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">

	function func1(){
		msg += "→1"
	}

	function func2(){
		msg += "→2"
	}

	var msg = "";
	
	func1();
	func2();
	
	alert(msg);

</script>
</head>
<body>
</body>
</html>

結果

→1→2


Ajaxの実行やsetTimeoutを使った処理など非同期処理がある場合、処理が行われる順番が前後することがあります

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">

	function func1(){

		// 100ミリ秒後に実行
		setTimeout(() => {
			msg += "→1"
		}, 100);
	}

	function func2(){
		msg += "→2"
	}

	var msg = "";
	
	func1();
	func2();
	
	setTimeout(() => {
		alert(msg);
	}, 200);

</script>
</head>
<body>
</body>
</html>

結果

→2→1


この非同期の処理に対して意図した順番で処理を行いたい場合、Promiseを使います。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">

	function func1(funcX){
		setTimeout(() => {
			msg += "→1"
			funcX();
		}, 100);
	}

	function func2(){
		msg += "→2"
	}

	var msg = "";
	
	// func1が終わったらfunc2を実行
	new Promise(func1).then(func2);	

	setTimeout(() => {
		alert(msg);
	}, 200);

</script>
</head>
<body>
</body>
</html>

結果

→1→2


順番通りに処理を行うだけでなく、例外処理に飛ばすこともできます。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">

	function func1(funcX,funcE){

		setTimeout(() => {

			msg += "→1"

			if(false){

				funcX();

			}else{

				funcE();
			}

		}, 200);
	}

	function func2(){

		setTimeout(() => {

			msg += "→2"

		}, 100);
	}
	
	function func3(){

		msg += "→3"

	}

	var msg = "";
	
	new Promise(func1).then(func2).catch(func3);	

	setTimeout(() => {

		alert(msg);

	}, 500);

</script>
</head>
<body>
</body>
</html>

結果

→1→3


単純な→1→2の処理だけでなく、処理を繋げて複雑も行えます。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">

	function func1(funcX,funcE){

		setTimeout(() => {

			msg += "→1"

			if(false){

				funcX();

			}else{

				funcE();
			}

		}, 200);
	}

	function func2(){
		setTimeout(() => {
			msg += "→2"
		}, 100);
	}
	
	function func3(){
		setTimeout(() => {
			msg += "→3"
		}, 100);
	}

	var msg = "";
	
	new Promise(func1).then(func2).catch(func3).then(func2);	

	setTimeout(() => {
		alert(msg);
	}, 500);

</script>
</head>
<body>
</body>
</html>

結果

→1→3→2


複数の非同期処理が全部終わったら、次の処理を行うことや、
複数の非同期処理のうち1つでも終わったら次の処理を行うこともできます。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">

	function func1(funcX){

		setTimeout(() => {

			msg += "→1"

			funcX();

		}, 100);
	}

	function func2(){
		msg += "→2"
	}
	
	function func3(){
		alert(msg);
	}

	var msg = "";

	const pro1 = new Promise(func1).then(func2);
	const pro2 = new Promise(func1).then(func2);

	// 全部が終わったら
	Promise.all([pro1, pro2]).then(func3);
	// 1つでも終わったら
	Promise.race([pro1, pro2]).then(func3);
	

</script>
</head>
<body>
</body>
</html>

結果

all
→1→2→1→2
race
→1→2


Promiseで行った非同期処理の順番制御はasync、awaitを使ってもできます。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">

	function func1(funcX){

		setTimeout(() => {

			msg += "→1"

			funcX();

		}, 200);
	}

	function func2(){

		msg += "→2"
	}
	
	// awaitを使う場合、functionにasyncを付ける
	async function func4(){

		// Promiseが終わるまで待つ
		await new Promise(func1).then(func2);
		alert(msg);
	}

	var msg = "";
	
	func4();

</script>
</head>
<body>
</body>
</html>

結果

→1→2


処理の順番を細かく確認すると以下になります。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">

	function func1(funcX){
	
		msg +="→2";
	
		setTimeout(() => {
			msg += "→6"
			funcX();
		}, 100);
	}

	function func2(){
		msg += "→7"
	}

	var msg = "";
	
	msg +="→1";

	var p = new Promise(func1);

	msg +="→3";

	p.then(func2);	

	msg +="→4";

	setTimeout(() => {
		alert(msg);
	}, 200);

	msg +="→5";

</script>
</head>
<body>
</body>
</html>


結果

→1→2→3→4→5→6→7


ページのトップへ戻る