Promise のブロックをなくしたい
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ Promise を返す関数で return new Promise のネストで一段が嫌
◆ resolve や reject を外に出してネストをなくす
◆ resolve や reject を外に出してネストをなくす
Promise を使う関数をつくるとこんな感じですよね
new Promise のブロックに全体を囲むことになります
これのせいで一段インデントが増えてしまいます
これをなくしたいです
非同期が入らない部分だけを外側に出しても 結局関数の中でかかないといけないところがでてきます
Promise の中に直接関数を書かなくても結局一段インデントがあるのは変わりません
ただ これだと一行目が見づらいですし 書くのも面倒です
Promise に渡す 関数を外側へ出す部分の処理は中身によらず共通なので 関数にしてしまいます
fn のほうは最初に 1 つ用意しておくだけなので 関数つくるたびに書くのは promi 関数の1行目のところです
これくらいなら そこまで書くのが大変でもなくなります
ですが 元々のに比べて ちょっと多いですし 見づらく覚えづらいのが欠点です
これだと一段ネストが減るのと比べると どっちもどっちです
丁寧に resolve, reject, promise って書いてる分 長めですけど ok, ng, p 程度にしてしまえばすごく短いです
また resolve などをローカル変数にしないでプロパティのままで良ければ受け取りは var obj = Pronise() だけで済みます
比較用に最初の
最後の return も入れると まだ文字数は多いですが 見やすさ的には Pronise のほうが好きです
スニペットに
Promise の内側のほうが Promise ってことがわかって良いって人もいると思いますし 個人の好みもあると思いますが 一段ネストが嫌って人にはおすすめです
それと if 文で非同期関数を実行したり同期的に実行したりがある場合に 常に Promise を返して then を通さなくても 同期的な処理のみになるときは直接値を返すのがやりやすいです
全体を return new Promise のブロックで囲んでしまうのと違い 好きなところで return すればその値が返せます
非同期になる時だけ return promise をすれば良いです
とはいっても 呼び出し元でどっちになるか判断できなければ返り値が Promise のインスタンスかどうかの判定が必要になるので あまり使えるケースはないかもですけど
function xhr(url){
return new Promise((resolve, reject) => {
var x = new XMLHttpRequest()
x.open("GET", url)
x.onload = eve => resolve(x)
x.onerror = eve => reject(x)
x.send()
})
}
return new Promise((resolve, reject) => {
var x = new XMLHttpRequest()
x.open("GET", url)
x.onload = eve => resolve(x)
x.onerror = eve => reject(x)
x.send()
})
}
new Promise のブロックに全体を囲むことになります
これのせいで一段インデントが増えてしまいます
これをなくしたいです
(0)
普通に考えると 最後に new Promise に渡す関数の引数を呼び出さないといけないので 関数の中に書くしかないです非同期が入らない部分だけを外側に出しても 結局関数の中でかかないといけないところがでてきます
Promise の中に直接関数を書かなくても結局一段インデントがあるのは変わりません
function pro(){
function main(ok, ng){
// anycode
setTimeout(ok, 2000)
}
return new Promise(main)
}
function main(ok, ng){
// anycode
setTimeout(ok, 2000)
}
return new Promise(main)
}
(1)
ですが 関数を外のスコープに出してしまえば ネストをなくせますfunction prom(){
var ok, ng, p = new Promise((a, b) => [ok, ng] = [a, b])
// anycode
setTimeout(ok, 2000)
return p
}
var ok, ng, p = new Promise((a, b) => [ok, ng] = [a, b])
// anycode
setTimeout(ok, 2000)
return p
}
ただ これだと一行目が見づらいですし 書くのも面倒です
(2)
そこで少し書く量を減らしてみますPromise に渡す 関数を外側へ出す部分の処理は中身によらず共通なので 関数にしてしまいます
function fn(obj){
return function(a, b){
obj.resolve = a
obj.reject = b
}
}
function promi(){
var obj = {}, p = new Promise(fn(obj))
// anycode
setTimeout(obj.resolve, 2000)
return p
}
書く量が減りましたreturn function(a, b){
obj.resolve = a
obj.reject = b
}
}
function promi(){
var obj = {}, p = new Promise(fn(obj))
// anycode
setTimeout(obj.resolve, 2000)
return p
}
fn のほうは最初に 1 つ用意しておくだけなので 関数つくるたびに書くのは promi 関数の1行目のところです
これくらいなら そこまで書くのが大変でもなくなります
ですが 元々のに比べて ちょっと多いですし 見づらく覚えづらいのが欠点です
これだと一段ネストが減るのと比べると どっちもどっちです
(3)
補助関数に任せる部分をもっと増やして毎回書く部分を短くしますfunction Pronise(){
var obj = {}
obj.promise = new Promise((a, b) => {
obj.resolve = a
obj.reject = b
})
return obj
}
function promis(){
var {resolve, reject, promise} = Pronise()
// anycode
setTimeout(resolve, 2000)
return promise
}
かなり減りましたねvar obj = {}
obj.promise = new Promise((a, b) => {
obj.resolve = a
obj.reject = b
})
return obj
}
function promis(){
var {resolve, reject, promise} = Pronise()
// anycode
setTimeout(resolve, 2000)
return promise
}
丁寧に resolve, reject, promise って書いてる分 長めですけど ok, ng, p 程度にしてしまえばすごく短いです
また resolve などをローカル変数にしないでプロパティのままで良ければ受け取りは var obj = Pronise() だけで済みます
比較用に最初の
function promise(){
return new Promise((resolve, reject) => {
// anycode
setTimeout(resolve, 2000)
})
}
return new Promise((resolve, reject) => {
// anycode
setTimeout(resolve, 2000)
})
}
最後の return も入れると まだ文字数は多いですが 見やすさ的には Pronise のほうが好きです
スニペットに
return new Promise((resolve, reject) => {
})
や})
var {resolve, reject, promise} = Pronise()
return promise
を登録してしまえば 書く手間はないですし それならネストのないこっちのほうがいいですreturn promise
Promise の内側のほうが Promise ってことがわかって良いって人もいると思いますし 個人の好みもあると思いますが 一段ネストが嫌って人にはおすすめです
それと if 文で非同期関数を実行したり同期的に実行したりがある場合に 常に Promise を返して then を通さなくても 同期的な処理のみになるときは直接値を返すのがやりやすいです
全体を return new Promise のブロックで囲んでしまうのと違い 好きなところで return すればその値が返せます
非同期になる時だけ return promise をすれば良いです
とはいっても 呼び出し元でどっちになるか判断できなければ返り値が Promise のインスタンスかどうかの判定が必要になるので あまり使えるケースはないかもですけど