b13d146b7796cbd1ca476c124001ea536bce9588
[WebKit-https.git] / Source / JavaScriptCore / builtins / PromiseConstructor.js
1 /*
2  * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 function all(iterable)
27 {
28     "use strict";
29
30     if (!@isObject(this))
31         @throwTypeError("|this| is not a object");
32
33     var promiseCapability = @newPromiseCapability(this);
34
35     var values = [];
36     var index = 0;
37     var remainingElementsCount = 1;
38
39     function newResolveElement(index)
40     {
41         var alreadyCalled = false;
42         return function @resolve(argument)
43         {
44             if (alreadyCalled)
45                 return @undefined;
46             alreadyCalled = true;
47
48             @putByValDirect(values, index, argument);
49
50             --remainingElementsCount;
51             if (remainingElementsCount === 0)
52                 return promiseCapability.@resolve.@call(@undefined, values);
53
54             return @undefined;
55         }
56     }
57
58     try {
59         for (var value of iterable) {
60             @putByValDirect(values, index, @undefined);
61             var nextPromise = this.resolve(value);
62             var resolveElement = newResolveElement(index);
63             ++remainingElementsCount;
64             nextPromise.then(resolveElement, promiseCapability.@reject);
65             ++index;
66         }
67
68         --remainingElementsCount;
69         if (remainingElementsCount === 0)
70             promiseCapability.@resolve.@call(@undefined, values);
71     } catch (error) {
72         promiseCapability.@reject.@call(@undefined, error);
73     }
74
75     return promiseCapability.@promise;
76 }
77
78 function race(iterable)
79 {
80     "use strict";
81
82     if (!@isObject(this))
83         @throwTypeError("|this| is not a object");
84
85     var promiseCapability = @newPromiseCapability(this);
86
87     try {
88         for (var value of iterable) {
89             var nextPromise = this.resolve(value);
90             nextPromise.then(promiseCapability.@resolve, promiseCapability.@reject);
91         }
92     } catch (error) {
93         promiseCapability.@reject.@call(@undefined, error);
94     }
95
96     return promiseCapability.@promise;
97 }
98
99 function reject(reason)
100 {
101     "use strict";
102
103     if (!@isObject(this))
104         @throwTypeError("|this| is not a object");
105
106     var promiseCapability = @newPromiseCapability(this);
107
108     promiseCapability.@reject.@call(@undefined, reason);
109
110     return promiseCapability.@promise;
111 }
112
113 function resolve(value)
114 {
115     "use strict";
116
117     if (!@isObject(this))
118         @throwTypeError("|this| is not a object");
119
120     if (@isPromise(value)) {
121         var valueConstructor = value.constructor;
122         if (valueConstructor === this)
123             return value;
124     }
125
126     var promiseCapability = @newPromiseCapability(this);
127
128     promiseCapability.@resolve.@call(@undefined, value);
129
130     return promiseCapability.@promise;
131 }