Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | |
3 * Copyright (C) 2006-2015 Eyeo GmbH | |
4 * | |
5 * Adblock Plus is free software: you can redistribute it and/or modify | |
6 * it under the terms of the GNU General Public License version 3 as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * Adblock Plus is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License | |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | |
16 */ | |
17 | |
18 function(global) | |
19 { | |
20 if ("Promise" in global) | |
21 return; | |
22 | |
23 var PENDING = 0; | |
kzar
2016/01/15 19:00:41
Nit: const?
Sebastian Noack
2016/01/19 11:34:17
const isn't supported in strict mode before Chrome
kzar
2016/01/19 14:49:27
Acknowledged.
| |
24 var FULFILLED = 1; | |
25 var REJECTED = 2; | |
26 | |
27 global.Promise = function(executor) | |
28 { | |
29 this._state = PENDING; | |
30 this._value = undefined; | |
31 this._subscriptions = []; | |
32 | |
33 try | |
34 { | |
35 executor(this._emit.bind(this, FULFILLED), | |
36 this._emit.bind(this, REJECTED)); | |
37 } | |
38 catch (reason) | |
39 { | |
40 this._emit(REJECTED, reason); | |
41 } | |
42 }; | |
43 | |
44 Promise.prototype = { | |
kzar
2016/01/15 19:00:41
Should be `global.Promise.prototype = {`?
Sebastian Noack
2016/01/19 11:34:17
As globals literally refers to the global scope, P
kzar
2016/01/19 14:49:27
Acknowledged.
| |
45 _dispatch: function(onFulfilled, onRejected, resolve, reject) | |
46 { | |
47 var callback = this._state == FULFILLED ? onFulfilled : onRejected; | |
48 | |
49 if (typeof callback == "function") | |
50 { | |
51 var result; | |
52 | |
53 try | |
54 { | |
55 result = callback(this._value); | |
56 } | |
57 catch (reason) | |
58 { | |
59 reject(reason); | |
60 return; | |
61 } | |
62 | |
63 Promise.resolve(result).then(resolve, reject); | |
64 } | |
65 else if (this._state == FULFILLED) | |
66 { | |
67 resolve(this._value); | |
68 } | |
69 else if (this._state == REJECTED) | |
70 { | |
71 reject(this._value); | |
72 } | |
73 }, | |
74 _dispatchSubscriptions: function() | |
75 { | |
76 if (this._state == REJECTED && this._subscriptions.length == 0) | |
kzar
2016/01/15 19:00:41
What if there are subscriptions but only for resol
Sebastian Noack
2016/01/19 11:34:17
No, in that case the error will be delegated to th
kzar
2016/01/19 14:49:27
Acknowledged.
| |
77 console.error('Uncaught (in promise)', this._value); | |
78 | |
79 for (var i = 0; i < this._subscriptions.length; i++) | |
80 this._dispatch.apply(this, this._subscriptions[i]); | |
81 | |
82 this._subscriptions = null; | |
83 }, | |
84 _emit: function(state, value) | |
85 { | |
86 if (this._state != PENDING) | |
87 return; | |
88 | |
89 this._state = state; | |
90 this._value = value; | |
91 | |
92 setTimeout(this._dispatchSubscriptions.bind(this), 0); | |
93 }, | |
94 then: function(onFulfilled, onRejected) | |
95 { | |
96 return new Promise(function(resolve, reject) | |
97 { | |
98 if (this._subscriptions) | |
99 this._subscriptions.push([onFulfilled, onRejected, resolve, reject]); | |
100 else | |
101 setTimeout( | |
kzar
2016/01/15 19:00:41
How come you're using setTimeout here and above?
Sebastian Noack
2016/01/19 11:34:18
The callbacks are supposed to be called asynchrono
kzar
2016/01/19 14:49:27
Acknowledged.
| |
102 this._dispatch.bind(this), 0, | |
103 onFulfilled, onRejected, resolve, reject | |
104 ); | |
105 }.bind(this)); | |
106 }, | |
107 catch: function(onRejected) | |
108 { | |
109 return this.then(undefined, onRejected); | |
110 } | |
111 }; | |
112 | |
kzar
2016/01/15 19:00:41
What about Promise.race?
Sebastian Noack
2016/01/19 11:34:17
I rather don't introduce dead code and unnecessary
kzar
2016/01/19 14:49:27
Acknowledged.
| |
113 Promise.resolve = function(value) | |
114 { | |
115 if (value instanceof Promise) | |
kzar
2016/01/15 19:00:41
The docs say that we should use the value straight
Sebastian Noack
2016/01/19 11:34:22
True, however this behavior isn't implemented in V
kzar
2016/01/19 14:49:27
Acknowledged.
| |
116 return value; | |
117 return new Promise(function(resolve, reject) { resolve(value); }); | |
118 }; | |
119 | |
120 Promise.reject = function(reason) | |
121 { | |
122 return new Promise(function(resolve, reject) { reject(reason); }); | |
123 }; | |
124 | |
125 Promise.all = function(promises) | |
126 { | |
127 return new Promise(function(resolve, reject) | |
128 { | |
129 var count = promises.length; | |
kzar
2016/01/15 19:00:41
Nit: Call this `remaining` instead of `count`?
Sebastian Noack
2016/01/19 11:34:18
Since this variable is used as well to set the siz
| |
130 var result = new Array(count); | |
131 | |
132 promises.forEach(function(promise, i) | |
133 { | |
134 promise.then( | |
135 function(value) | |
136 { | |
137 result[i] = value; | |
138 if (--count == 0) | |
139 resolve(result); | |
140 }, | |
141 reject | |
142 ); | |
143 }); | |
144 }); | |
145 }; | |
146 }(this); | |
OLD | NEW |