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
ページのトップへ戻る