久し振りに使おうとしたときに忘れていたので備忘録。
Promise
await/asyncを使おうとか、アロー関数式での表現とかありますが、
まずこのPromiseに立ち返った方が良さげ。
そもそもPromiseとは
プロミス (Promise) は、作成された時点では分からなくてもよい値へのプロキシーです。非同期のアクションの成功値または失敗理由にハンドラーを結びつけることができます。これにより、非同期メソッドは結果の値を返す代わりに、未来のある時点で値を提供するプロミスを返すことで、同期メソッドと同じように値を返すことができるようになります。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise
特徴
上記の通り、未来のある時点での値(何らかの処理の結果)を提供することができるので、以下のように “.then”で処理を書くことができる。
const promise = doSomething();
const promise2 = promise.then(successCallback, failureCallback);
orconst promise2 = doSomething().then(successCallback, failureCallback);
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Using_promises
上記のコードだと、” doSomething “という処理の結果を受けて、
successCallback と failureCallback という処理をかませることができる。
書き方
コンストラクターとしてのPromiseは以下のように書く。
const promise1 = new Promise( function(resolve, reject){
resolve('hogehoge');
});
promise1.then( function(value){
console.log(value);
// hogehoge
});
上手く行ったときと上手く行かなかったときという、2つの関数を引数に用意する。
このコードだと 処理の中でresolve関数に hogehogeを当てている。処理に問題がなければ、このresolve関数の値がthenに渡される。
なので、promise1.thenの処理としては valueにresolve関数の値である hogehogeが入っている。
resolve、rejectというのは御作法みたいなもの。以下のようにも書ける。
const promiseA = new Promise(
function(okFuncion,ngFuncion){
okFunction(777);
});
// 作法の通りにresolve, rejectを入れた方が良い。
値を受け渡していく、
つまり、ピタゴラスイッチみたいに値を一段一段処理していくような使い方も出来る。
もし、いくつかの処理を並列に実行したいときは Promise.allメソッドを使う。
Promise.all(
[promise1,
promise2,
promise3]
).then((values) => {
console.log(values);
});
// valuesには、それぞれのpromise1~3で設定した resolveの値が配列に入っている [resolve1, resolve2, resolve3]
そのほか、Promiseには以下のようなメソッドが用意されている。
- Promise.catch() :暗黙的?に設定されたrejectedの値を扱う
- Promise.finally() : resolveだろうがrejectだろうが関係なく動く処理
Promiseではtry/catch文を使うことができない。上記のcatchは rejectedの処理として扱われてしまうのでtry/catchとは少し違う。
async/await処理ではtry/catchを使うことができる。
asyncとは
非同期関数の宣言。
asyncだけでも成り立つ。(awaitと必ずセットでなければエラーが出るというものではない)
async function aaabbb() {
return Promise.resolve(2021);
}
aaabbb().then(function(value) {
console.log(value)
});
// returnでresolveを返しているだけ・・・
await
await 式は返されたプロミスが履行されるか拒否されるまで実行を中断することで、プロミスを返す関数をあたかも同期しているかのように動作させます。プロミスの解決済みの値は、await 式の返値として扱われます。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function
Promiseの処理が終わるまで(resolveとrejectedが設定されるまで)実行を中断する。
つまり、Promiseとasync/awaitを組み合わせることで、非同期でビシバシ動いているJavaScriptの関数群に分かりやすく段階を付けることが出来る。
基本の形
function resolve2021() {
return new Promise( function(resolve){
resolve(2021);
});
}
async function asyncFunction2021() {
const result = await resolve2021();
console.log(result);
}
asyncFunction2021();
// console.log = 2021
終わりに
簡単なスクリプトだと思ってサラなJavaScriptを書いていて、後からasync/awaitあった方が良いなと思い始め備忘録にまとめた。
ここまで書いて、そもそも論でPromise-async/awaitの世界のコード設計してないとダメだなとまで思い出した。(部分的にPromise-async/awaitを入れるのではなく、スクリプト全体のリファクタリングをしたくなってきた(すべき))