1<?php
2
3namespace Sabre\Event\Promise;
4
5use Sabre\Event\Promise;
6
7/**
8 * This file contains a set of functions that are useful for dealing with the
9 * Promise object.
10 *
11 * @copyright Copyright (C) 2013-2015 fruux GmbH (https://fruux.com/).
12 * @author Evert Pot (http://evertpot.com/)
13 * @license http://sabre.io/license/ Modified BSD License
14 */
15
16
17/**
18 * This function takes an array of Promises, and returns a Promise that
19 * resolves when all of the given arguments have resolved.
20 *
21 * The returned Promise will resolve with a value that's an array of all the
22 * values the given promises have been resolved with.
23 *
24 * This array will be in the exact same order as the array of input promises.
25 *
26 * If any of the given Promises fails, the returned promise will immidiately
27 * fail with the first Promise that fails, and its reason.
28 *
29 * @param Promise[] $promises
30 * @return Promise
31 */
32function all(array $promises) {
33
34    return new Promise(function($success, $fail) use ($promises) {
35
36        $successCount = 0;
37        $completeResult = [];
38
39        foreach ($promises as $promiseIndex => $subPromise) {
40
41            $subPromise->then(
42                function($result) use ($promiseIndex, &$completeResult, &$successCount, $success, $promises) {
43                    $completeResult[$promiseIndex] = $result;
44                    $successCount++;
45                    if ($successCount === count($promises)) {
46                        $success($completeResult);
47                    }
48                    return $result;
49                }
50            )->error(
51                function($reason) use ($fail) {
52                    $fail($reason);
53                }
54            );
55
56        }
57    });
58
59}
60
61/**
62 * The race function returns a promise that resolves or rejects as soon as
63 * one of the promises in the argument resolves or rejects.
64 *
65 * The returned promise will resolve or reject with the value or reason of
66 * that first promise.
67 *
68 * @param Promise[] $promises
69 * @return Promise
70 */
71function race(array $promises) {
72
73    return new Promise(function($success, $fail) use ($promises) {
74
75        $alreadyDone = false;
76        foreach ($promises as $promise) {
77
78            $promise->then(
79                function($result) use ($success, &$alreadyDone) {
80                    if ($alreadyDone) {
81                        return;
82                    }
83                    $alreadyDone = true;
84                    $success($result);
85                },
86                function($reason) use ($fail, &$alreadyDone) {
87                    if ($alreadyDone) {
88                        return;
89                    }
90                    $alreadyDone = true;
91                    $fail($reason);
92                }
93            );
94
95        }
96
97    });
98
99}
100
101
102/**
103 * Returns a Promise that resolves with the given value.
104 *
105 * If the value is a promise, the returned promise will attach itself to that
106 * promise and eventually get the same state as the followed promise.
107 *
108 * @param mixed $value
109 * @return Promise
110 */
111function resolve($value) {
112
113    if ($value instanceof Promise) {
114        return $value->then();
115    } else {
116        $promise = new Promise();
117        $promise->fulfill($value);
118        return $promise;
119    }
120
121}
122
123/**
124 * Returns a Promise that will reject with the given reason.
125 *
126 * @param mixed $reason
127 * @return Promise
128 */
129function reject($reason) {
130
131    $promise = new Promise();
132    $promise->reject($reason);
133    return $promise;
134
135}
136