public static function race($promisesOrValues)
    {
        $cancellationQueue = new CancellationQueue();

        return new Promise(function($resolve, $reject, $cancel) use($promisesOrValues, $cancellationQueue) {
            self::doResolve($promisesOrValues)
                ->done(function($array) use($resolve, $reject, $cancel, $cancellationQueue) {
                    if (!is_array($array) || !$array)
                    {
                        $resolve();
                        return;
                    }

                    $fulfiller = function($value) use($resolve, $cancellationQueue) {
                        $resolve($value);
                        $cancellationQueue();
                    };

                    $rejecter = function($reason) use($reject, $cancellationQueue) {
                        $reject($reason);
                        $cancellationQueue();
                    };

                    foreach ($array as $promiseOrValue)
                    {
                        $cancellationQueue->enqueue($promiseOrValue);

                        self::doResolve($promiseOrValue)
                            ->done($fulfiller, $rejecter, $cancel);
                    }
                }, $reject, $cancel);
        }, $cancellationQueue);
    }