非同期処理を同期処理のように扱うには
JavaScriptで常に問題になるのが非同期処理ではないでしょうか。かつてのコールバック地獄であったり、現在のPromiseによる処理など常に非同期処理に起因しています。そこで苦労されている方も多いでしょう。
例えばAjaxを使う際など、関数の戻り値としてPromiseを返すことがあります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function ajax() { | |
return $.ajax({ | |
url: '/' | |
}); | |
} | |
function main() { | |
let p = ajax(); | |
} |
このような形の場合、返り値を受け取った側では必然的に一つネストが発生します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function main() { | |
let p = ajax(); | |
p.then(function(results) { | |
// Ajaxの処理成功時 | |
}) | |
} |
コールバック時ほどではありませんが、ネストが深くなるのを嫌がる人は多いでしょう。そこで使えるのが次のような実装です。ネストが一段低くなっているのが分かるでしょうか。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function main(results) { | |
if (!results) | |
let p = ajax(); | |
if (typeof p == 'object' && typeof p.then == 'function') { | |
p.then(function(results) { | |
main(results); | |
return; | |
}) | |
} | |
// Ajaxの処理成功時 | |
} |
ajax関数の返値がPromiseオブジェクトであれば(then関数が定義されていれば)、処理を実行して結果を自分自身(main関数)に渡します。2回目に実行されたmain関数ではresultsが入っていますのでajax関数は実行しません。その結果、ajax関数の結果(results)をネストを深くすることなく利用できます。
hifiveで実装するには
実はhifiveにおいてコントローラ側で処理を実行する際には常にこのように実装されています。関数の引数がPromiseであれば、まず処理を実行して結果を再度自分自身に渡します。こうすることで無闇にネストが深くなるのを防いでいます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if (h5.async.isPromise(data)) { | |
data.done(this.own(function(d) { | |
this.setData(d); | |
})); | |
return; | |
} |
JavaScriptを使った開発で嫌がられるのが非同期処理に伴うネストが深いコードになります。ちょっとした工夫で防げますのでぜひ活用してください。
コメントは受け付けていません。