LoginSignup
0
0

More than 5 years have passed since last update.

並列に実行している非同期処理(Promise)で最後に実行したやつだけresolvedにする

Last updated at Posted at 2015-12-24

例えば、サーバー上のリソースをajaxで引っ張ってきて、その結果をビューに反映するようなコードを書いたとします。雑に書くと以下の様な感じで。

fetch('/api/items/1').then(render);
fetch('/api/items/2').then(render);

/api/items/1/api/items/2はどちらが先に返ってくるかは保証されないですね。後のほうが先に返ってくると、多分想定とは違う結果になるかと思います。

そこで、実行回数をカウントしておいて、resolvedになったとき記録しておいたカウント数と比較して一致したときは最後に実行したものなのでそのまま後ろに流す、違ったらrejectするという層を作ります。

var latest = (() => {
  var ids = {};

  return key => {
    ids[key] = ids[key] || 0;
    var id = ++ids[key];
    return x => id === ids[key] ? x : Promise.reject(new Error('old promise!'));
  };
})();

これで並列に最後に実行した非同期処理のなかで最後に実行したやつだけresolvedになります、めでたし。

var sleep = t => new Promise(resolve => setTimeout(() => resolve(t), t));
var log = console.log.bind(console);
var error = console.error.bind(console);

sleep(100).then(latest('a')).then(log, error);
sleep(200).then(latest('a')).then(log, error);
sleep(300).then(latest('a')).then(log, error);
sleep(150).then(latest('a')).then(log, error); // resolved
sleep(340).then(latest('b')).then(log, error);
sleep(120).then(latest('b')).then(log, error);
sleep(110).then(latest('b')).then(log, error);
sleep(200).then(latest('b')).then(log, error); // resolved
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0