◆ Promise ならではっていい例が見当たらない
◆ for 文で URL のデータ取得と setTimeout で時間あけるのを順番に実行する

前回別にコールバック渡してもいいかなーって感じだったのでもっと Promise が役立つ例を考えていました
返り値を使えるんだから for 文でループしたいときとか便利じゃない?とひらめいたのでこんなのをつくってみました

やること

適当な URL ですが
http://sample.net/test/1
http://sample.net/test/2
(略
http://sample.net/test/10
と 1 から 10 まで取得します
そのときに 一気にアクセスするのはサーバに負担がかかるので取得してから 5 秒まって次のに進みます

Promise 版

var url_base = "http://sample.net/test/"
var p = Promise.resolve()
var data = []
for(var i=0;i<10;i++){
p = p.then(load(i)).then(wait(5000))
}
p.then(_ => console.log(data))

function load(num){
return function(){
return fetch(url_base + num)
.then(e => e.text())
.then(text => data[num] = text)
}
}

function wait(msec){
return function(){
return new Promise(resolve => {
setTimeout(resolve, msec)
})
}
}

 見やすく書けました

コールバック関数版

これってコールバックだとどうやるのがいいんだろう

………
………………
………………………
できた

var url_base = "http://sample.net/test/"
var queue = []
var data = []
for(var i=0;i<10;i++){
queue.push(load(i))
queue.push(wait(5000))
}
queue.push(_ => console.log(data))
run(queue)

function load(num){
return function(next){
return fetch(url_base + num)
.then(e => e.text())
.then(text => {
data[num] = text
next()
})
}
}

function wait(msec){
return function(next){
return setTimeout(_ => next(), msec)
}
}

function run(q){
(function controller(){
var fn = q.shift()
fn && fn(controller)
})()
}

fetch は返り値が Promise なのでそこだけは Promise になってます

そこまで作りは変わってないです
やることのリストをキューに詰めていって リストに全部入ったら run で実行します
Promise という機能自体がない分ちょっとコード量は増えてますが 特に困る量でもないですし コールバックにしないといけないと辛いというほどではないです

fetch 使えないから xhr つかわないといけない とか es6 使えないから es5 で書かないとダメというのよりは嫌じゃないです

結局今回も Promise だからこそかなり便利!っていうのはみつからなかったです