Promiseとasync awaitを理解したい
http://i0.wp.com/techinpink.com/wp-content/uploads/2017/02/promise.png
これを読みながら自分が何がわからないのかを整理しよう
Promiseなんやねん
Promise は 非同期処理を操作するオブジェクト、およびその仕組
Promise は処理の成功・失敗をインターフェース的に限定してくれている
もともとふわっとは理解しているつもり…
Promiseのつかいかた
PromiseはPromiseインスタンスに対してインスタンスメソッドでコールバック関数を登録する使い方をする
code:js
const promise = doSomething();
promise.then(successCallback, failureCallback);
// もしくはこう
doSomething().then(successCallback, failureCallback);
thenに引数がひとつなら成功コールバックだけ登録できる
ていうか thenの引数の関数の引数はオプション
Promiseチェーンを作ると、前段の返り値のPromiseの結果が下段に流れていく
code:js
const promise = doSomething();
doSomething()
.then(result => doSomethingElse(result));
// は以下と同じなはず…
doSomething()
.then(function(result) {
return doSomethingElse(result);
},
null // failureCallback
);
使い方はとりあえずだいじょうぶそう
Promiseのつくりかた
基本的には自分でPromiseを作る必要はないはず(だいたいの非同期処理の返り値がPromiseを返しているはず)
つくるならこういう感じ
code:js
var promise = new Promise(function(resolve, reject) {
// 非同期の処理
// 処理が終わったら、resolve または rejectを呼ぶ
});
// ふつうはPromise.then(successCallback, failureCallback)な感じで使う
// ので、生成を気にすることは少ない、はず。
Promiseを返さない古い非同期処理をPromiseでラップしてやるときに使うんじゃ
Promiseを返さない非同期処理の代表格が setTimeout である
これは生成時に成功/失敗のコールバックを渡す形式のAPIである
これをPromiseでラップしてやることでいい感じに書けるようになる
code:js
// 素朴にsetTimeout()を使うとこんな感じ
// 成功時コールバック関数と待ち時間を渡している
window.setTimeout(alert("1秒待ちました"), 1000);
// これをどう書き直せばよいか?
// Promiseを返す関数にし、Promiseの成功コールバックにsetTimeoutを渡すような関数を書けば良い
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
// 補完して書き直すと、きっとこう
// これでようやく分かった気がする
const wait = function (ms) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, ms);
// rejectは使わない
});
};
こうしておけば、 setTimeout を使わずともPromise.thenで後付けコールバックできて便利になる!
code:js
// setTimeoutを呼ぶかわりにwait()を呼ぶようにする
wait(10000)
.then(() => doSomething(alert("10秒待ったゾ")))
.catch(failureCallback);
// なお .then(doSomething()) としちゃいけない
// そうするとその場でdoSomethingが実行されてしまう
// なぜかというと、0引数関数リテラルなら doSomething (not doSomething() )を渡せばいいが、
// 引数があるやつは関数リテラルを渡せない
// そのため即時関数を作って () => doSomething(args) としないと遅延実行ができない
// by azmax
async と await
Promiseがわかれば素直に理解できるはず…
async は関数の戻り値を非同期にするキーワード
code:js
async function hoge(){}
const fuga = async () => {}
await は async キーワードで書いた非同期な戻り値を待ってくれる
というか、 Promise が返ってくる場合、 Promise が resolve されるまで待ってくれる
await は Async Functionの中でしか使用することができない。
code:js
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
const add = (a, b) => new Promise(resolve => resolve(a + b));
}
// たぶんこんな感じで使えるんだと思う
async () => {
let res = 1 + (await wait(1000).then(() => add(1, 2)));
console.log(res);
}
あとの使用例は↑のqiita記事で・・・