Promise処理について雑にまとめる
この記事は公開から1年以上が経過しています。内容が一部古い箇所があります。
Promise とは
簡単に言うと非同期処理を行う時にコールバック地獄、ネストの深層化を回避して記述をだいぶ楽にするオブジェクト。ES2015 です。
非同期処理とは
例えば A の処理の後に B の処理があるとする。JavaScript とはシングルスレッドで動く=同時に処理を行うということができないものなので、通常であれば A、B の処理で動く。その辺の順番を変えて処理を行うのを非同期処理という。
分かりやすい例は Api と連携する Ajax 通信を受け取ったレスポンス(200 とか 404 とか)の結果によって処理を行うやつ。
非同期処理の例
- setTimeout
- setInterval
- addEventListener(イベントハンドラ)
- jQuery.Deferred
- Promise ← これ
- async/await
例 — ajax 通信後順番に処理を行う
var fetchSomething1 = function (done) {
// API1にアクセス
doAjaxStuff(someOptions, {
success: function (data) {
done(); // 成功したら渡されたfunctionを実行
},
});
};
// fetchSomething1と同じようにそれぞれ別のAPIにアクセスするfunction群
var fetchSomething2 = function (done) {
/* 省略 */
};
var fetchSomething3 = function (done) {
/* 省略 */
};
var fetchSomething4 = function (done) {
/* 省略 */
};
var doSomethingFinally = function () {
// APIにアクセスして取得してきたデータを使って何かする
};
こういう関数を登録しておき、順番に処理を行うとする。通常だと
fetchSomething1(function () {
fetchSomething2(function () {
fetchSomething3(function () {
fetchSomething4(doSomethingFinally);
});
});
});
こうなるが、これが
fetchSomething1()
.then(fetchSomething2)
.then(fetchSomething3)
.then(fetchSomething4)
.then(doSomethingFinally);
こうなる。コールバック地獄、ネスト深層化問題の回避がよく分かる。
// Callback
fetchSomething1(function() {
fetchSomething2(function() {
fetchSomething3(function() {
fetchSomething4(doSomethingFinally, function() {
// fetchSomething4のエラー処理
});
}, function() {
// fetchSomething3のエラー処理
});
}, function() {
// fetchSomething2のエラー処理
});
}, function() {
// fetchSomething1のエラー処理
});
// Promise then & catch
fetchSomething1()
.then(fetchSomething2)
.catch(/* fetchSomething1のエラー処理 */);
.then(fetchSomething3)
.catch(/* fetchSomething2のエラー処理 */);
.then(fetchSomething4)
.catch(/* fetchSomething3のエラー処理 */);
.then(doSomethingFinally)
.catch(/* fetchSomething4のエラー処理 */);
エラー処理も含めると更に分かりやすくなる。こういう風に書くと見やすくなってメンテナンス性も上がりますね。
ブラウザ対応状況 — CanIUse
発表されてからだいぶ時間が経ったのでブラウザ対応であれば、現状 IE11 以外だったら大丈夫。
パフォーマンス対決
jsPrefにて計測。
Promise vs Callback
Native Promise vs Callback
非同期処理だとそこまで差はないけどそのまま使う Promise だと圧倒的に Callback のがパフォーマンス良い。素で使わないほうがよさそう。