juchelka / flow

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

flow is tiny piece of code, that uses miracle of PHP 5.5 Generators and yield keyword and allows you to write asynchronous code that looks just like imperative one, but it uses under the hood React.PHP promises.

// this flow code and next snippet does tha same thing
$p = flow(function () {
  $a = yield asyncTask(1);
  $b = yield asyncTask($a + 10);
       yield asyncTask($b + 100)
});

$p = asyncTask(1)->then(function ($a) {
  return asyncTask($a + 10)->then(function ($b) {
    return asyncTask($b + 100);
  });
});

flow function always return Promise

If yielded promise fails, it deosn't throw exception into generator code, but rest of the code is not executed (and error is propagated).

flow(function () {
  $a = yield asyncTask(1);
  $b = yield asyncTask(2); // if this promise fails, next lines are not executed and flow returns this failed promise
  $b = yield asyncTask(3);
  yield [$a, $b, $c];
});

You can yield not only promises. It's useful for returning final value, as shown in previous example.

You can use loops (code looks just like imperative one, but it's asynchronous and uses promises under the hood).

flow(function() {
  $profile = (yield fetchProfile('@kaja47'));

  $ids = [];
  $cursor = '-1';
  do {
    $fs = (yield fetchFollowers($profile->id, $cursor));
    $ids = array_merge($ids, $fs->ids);
    $cursor = $fs->next_cursor_str;
  } while ($cursor != "0")

  yield [$profile, $ids];
});

And exceptions

flow(function () use ($id) {
  if ($id < 0)
    throw new Exception("id should be equal or greater that zero");

  $profile = yield fetchProfile($id);
  $lastArticles = yield fetchLastArticles($id, $profile->showLastArticles);
  yield [$profile, $lastArticles];
});

This produce rejected promise if $id is lower than zero, with exception as value of rejected promise.

About