Chapter 45

Flowで非同期処理を行う

alkn203
alkn203
2021.09.18に更新

flow

Flowとは

phina.jsには、Flowという非同期処理を実装するためのクラスが用意されています。

Flowの使い方

// flow設定
var flow = Flow(function(resolve) {
  RectangleShape()
    .addChildTo(self)
    .setPosition(self.gridX.center(), 0)
    .tweener.to({y: self.gridY.center()}, duration)
    .call(function() {
      resolve('flow done');
      console.log(message);
    }).play();
});
  • 非同期で実行したい処理をFlow内に記述します。
  • 処理が終わった後は、resolveを呼び出します。
  • 上の例では、tweenerを使って一定時間かけて画面中央まで移動した後に、resolveをコールするようにしています。

後処理の記述

// resoveで実行される
flow.then(function() {
  rect.tweener.to({y: self.gridY.width}, duration).play();
});
  • resolveが呼ばれると、Flowクラスのメソッドthenが実行されるため、この中に後から実行したい処理を記述します。

複数のFlowを取り扱う

これまでは1つのFlowオブジェクトを取り扱ってきました。
1つであればtweenerを使えば似たような処理が出来なくもないですが、さらにFlowでは複数の非同期処理をウォッチすることができます。

サンプルコード

コードを見る
phina.globalize();
// メインシーン
phina.define('MainScene', {
  superClass: 'DisplayScene',
  // コンストラクタ
  init: function() {
    // 親クラス初期化
    this.superInit();
    // 背景色
    this.backgroundColor = 'black';
  
    var self = this;
    var flows = [];
    
    (10).times(function(i) {
      // flow作成
      var flow = Flow(function(resolve) {
        var x = Random.randint(64, self.gridX.width - 64);
        var y = Random.randint(64, self.gridY.width - 64);
        var duration = Random.randint(500, 5000); 
        // ランダムな位置に円を作成
        CircleShape()
          .addChildTo(self)
          .setPosition(x, y)
          .tweener.fadeOut(duration) // フェードアウト
          .call(function() {
            resolve(i + 'done');
          }).play();
        });
        // 配列に追加
        flows.push(flow);
    });
    // 全てのflow実行後
    Flow.all(flows).then(function(messages) {
      console.log('all done!', messages);
    });
  },
});
// メイン
phina.main(function() {
  var app = GameApp({
    startLabel: 'main',
  });
  app.run();
});
  • 実行すると、ランダムな位置に円が表示されランダムな時間でフェードアウトします。
  • 最後の円がフェードアウトしてから、メッセージがコンソールに表示されます。

Flowの配列を作って追加する

var flows = [];

(10).times(function(i) {
  // flow作成
  var flow = Flow(function(resolve) {
    var x = Random.randint(64, self.gridX.width - 64);
    var y = Random.randint(64, self.gridY.width - 64);
    var duration = Random.randint(500, 5000); 
    // ランダムな位置に円を作成
    CircleShape()
      .addChildTo(self)
      .setPosition(x, y)
      .tweener.fadeOut(duration) // フェードアウト
      .call(function() {
        resolve(i + 'done');
      }).play();
    });
    // 配列に追加
    flows.push(flow);
  • Flowを格納する配列を作ってpushしています。

Flow.allで全てのFlowをウォッチ

// 全てのflow実行後
Flow.all(flows).then(function(messages) {
  console.log('all done!', messages);
});
  • Flow.allの引数にウォッチしたいFlowの配列を代入すると、与えれられた全ての非同期処理の終了をウォッチすることができます。
  • 今回は配列でまとめて代入しましたが、個々にFlowを作成して代入することもできます。

runstantプロジェクト

https://runstant.com/alkn203/projects/017e556a
https://runstant.com/alkn203/projects/9665202b