/** * Merges an observable sequence of observables into an observable sequence. * * @param ObservableInterface $observables * * @return ObserverInterface */ public static function mergeAll(ObservableInterface $sources) { // todo: add scheduler return new AnonymousObservable(function ($observer, $scheduler) use($sources) { $group = new CompositeDisposable(); $isStopped = false; $sourceSubscription = new SingleAssignmentDisposable(); $group->add($sourceSubscription); $sourceSubscription->setDisposable($sources->subscribeCallback(function ($innerSource) use(&$group, &$isStopped, $observer, &$scheduler) { $innerSubscription = new SingleAssignmentDisposable(); $group->add($innerSubscription); $innerSubscription->setDisposable($innerSource->subscribeCallback(function ($nextValue) use($observer) { $observer->onNext($nextValue); }, function ($error) use($observer) { $observer->onError($error); }, function () use(&$group, &$innerSubscription, &$isStopped, $observer) { $group->remove($innerSubscription); if ($isStopped && $group->count() === 1) { $observer->onCompleted(); } }, $scheduler)); }, function ($error) use($observer) { $observer->onError($error); }, function () use(&$group, &$isStopped, $observer) { $isStopped = true; if ($group->count() === 1) { $observer->onCompleted(); } }, $scheduler)); return $group; }); }