Promiseとasync、awaitの使い方を理解するために書いたサンプルコード。 setTimeoutを使って1秒後に画面に文字列を出力する。
Promiseとthen()
Promiseオブジェクトの生成とthen()メソッドの利用例。
<html> <head> <meta charset="utf-8"/> <title>Promiseとthen()</title> </head> <body> <button onclick="main()">Run</button> <div id="output"> </div> <script> function print(text) { const element = document.getElementById('output'); element.innerText = element.innerText + text + '\n'; } function main() { const promise = slowFunction(); // Promiseの処理が完了したら(resolveが呼ばれたら)、結果を出力 promise.then(result => { // resolve関数の引数で渡された値がresultに格納される print(result); }) } function slowFunction() { // Promiseオブジェクトを返す return new Promise(resolve => { // 1秒後にresolveを呼び出す setTimeout(() => { resolve("Result"); }, 1000); }); } </script> </body> </html>
Promiseとreject()
Promiseオブジェクトの例外処理、reject()とcatch() メソッドを使う。
reject()を呼ぶと、catch()メソッドに渡したコールバック関数が実行される。
<html> <head> <meta charset="utf-8"/> <title>Promiseとreject、catch()</title> </head> <body> <button onclick="main()">Run</button> <div id="output"> </div> <script> function print(text) { const element = document.getElementById('output'); element.innerText = element.innerText + text + '\n'; } function main() { const promise = slowFunction(); // Promiseの処理が完了したら(resolveが呼ばれたら)、結果を出力 promise.then(result => { print("Success"); }).catch((message) => { // reject関数で渡された引数がcatchの引数に渡されてくる print(message); }) } function slowFunction() { return new Promise((resolve, reject) => { // 1秒後にrejectを呼ぶ setTimeout(() => { // エラー内容などはreject関数の引数で渡す reject("Error!"); }, 1000); }); } </script> </body> </html>
Promiseとreject、catch() - JSFiddle
Promiseとthrow
then()メソッドに渡したコールバック関数内で例外を発生させる場合はthrowを使う。 catchメソッドに渡したコールバック関数が呼ばれる。
<html> <head> <meta charset="utf-8"/> <title>Promiseとthrow、catch()</title> </head> <body> <button onclick="main()">Run</button> <div id="output"> </div> <script> function print(text) { const element = document.getElementById('output'); element.innerText = element.innerText + text + '\n'; } function main() { const promise = slowFunction(); // When it is finished promise(called resolved), then output the result. promise.then(result => { throw new Error("Error!"); }).catch((error) => { // result is Error object. print(error); }) } function slowFunction() { // Returns promise object. return new Promise((resolve, reject) => { // Execute resolve function after a second. setTimeout(() => { resolve("Result"); }, 1000); }); } </script> </body> </html>
Promiseとthrow、catch() - JSFiddle
Promiseをawait構文で待つ
Promiseオブジェクトの処理が終わるのをawait構文で待つ例。
<html> <head> <meta charset="utf-8"/> <title>Promiseとawait構文</title> </head> <body> <button onclick="main()">Run</button> <div id="output"> </div> <script> function print(text) { const element = document.getElementById('output'); element.innerText = element.innerText + text + '\n'; } // "await"構文は"async"キーワード付きの関数内でしか使えない async function main() { // awaitで呼び出すと、resolveかrejectが呼ばれるまで止まる // resolveで渡された引数は、戻り値として返却される result = await slowFunction(); print(result); } function slowFunction() { // Promiseオブジェクトを返す return new Promise(resolve => { // 1秒後にresolve関数を呼ぶ setTimeout(() => { resolve("Result"); }, 1000); }); } </script> </body> </html>
asyncとawait
async functionで関数を実装すれば、Promiseの発行を減らせるのと、then()のメソッドチェーン地獄がマシになる
<html> <head> <meta charset="utf-8"/> <title>asyncとawait</title> </head> <body> <button onclick="main()">Run</button> <div id="output"> </div> <script> function print(text) { const element = document.getElementById('output'); element.innerText = element.innerText + text + '\n'; } // "await"構文は"async"キーワード付きの関数内でしか使えない async function main() { // async functionの結果が返ってくるまで待つ result = await slowFunction(); print(result); } async function slowFunction() { // setTimeoutをPromiseでラップし、終わるまでawaitで待つ await new Promise(resolve => setTimeout(resolve, 1000)); // async functionの結果として文字列を返却 return "Result"; } </script> </body> </html>
async、awaitと例外処理
async、awaitを使う場合、例外はthrowで発生させて、try catch構文で処理できる。
<html> <head> <meta charset="utf-8"/> <title>asyncとawait、throw()</title> </head> <body> <button onclick="main()">Run</button> <div id="output"> </div> <script> function print(text) { const element = document.getElementById('output'); element.innerText = element.innerText + text + '\n'; } // "await"構文は"async"キーワード付きの関数内でしか使えない async function main() { // async functionでthrowされた例外はtry catch構文で処理できる try { result = await slowFunction(); print(result); } catch (error) { print(error); } } async function slowFunction() { // setTimeoutをPromiseでラップし、終わるまでawaitで待つ await new Promise(resolve => setTimeout(resolve, 1000)); // throwで例外を発生させる throw new Error("Error in async function!"); return "Result"; } </script> </body> </html>
asyncとawait、throw() - JSFiddle