├── test.png
├── src
├── index.js
├── es6_extensions.js
├── async_callback.js
└── core.js
├── webpack.config.js
├── .gitignore
├── index.html
├── test.js
├── README.md
├── .npmignore
├── index.js
├── package.json
└── dist
├── promise.esm.js
├── promise.common.js
└── promise.min.js
/test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imtaotao/promise/HEAD/test.png
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import './es6_extensions'
2 | import Promise from './core'
3 |
4 | export default Promise
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | entry: './index.js',
3 | output: {
4 | path: 'bundle.js',
5 | },
6 | devtool: '#cheap-module-eval-source-map',
7 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # vim
2 | *~
3 | *.sw?
4 |
5 | # misc editing tools
6 | .vscode/
7 | tags
8 |
9 | #mac
10 | *.DS_Store
11 |
12 | # build tools
13 | node_modules/
14 |
15 | # logfiles
16 | *.log
17 | .idea/
18 |
19 | #npm
20 | yarn.lock
21 | package-lock.json
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Promise by taotao
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | const Promise = require('./dist/promise.min')
2 |
3 | exports.deferred = function () {
4 | let resolve, reject
5 | const promise = new Promise(function (_resolve, _reject) {
6 | resolve = _resolve
7 | reject = _reject
8 | })
9 | return {
10 | promise,
11 | resolve,
12 | reject,
13 | }
14 | }
15 |
16 | exports.resolved = Promise.resolve
17 | exports.rejected = Promise.reject
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Promise/es6
2 | [![NPM version][npm-image]][npm-url]
3 |
4 | This `Promise` case is implemented in `es6`, and it is compatible with the native `async/await` function through the official unit test of the promise. This case is for study only, if it is used in a production environment, you can use the files in the `dist` directory.
5 |
6 | ### test
7 | You can use `npm i` or `yarn` install dependencies, then use `npm run test` or `yarn test` to test.
8 |
9 | 
10 |
11 | [npm-url]: https://www.npmjs.com/package/es2015-promise
12 | [npm-image]: https://img.shields.io/npm/v/es2015-promise.svg
13 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # vim
2 | *~
3 | *.sw?
4 |
5 | # generic editing tools
6 | tags
7 | tags.lock
8 |
9 | # mac
10 | *.DS_Store
11 |
12 | # wandows
13 | .vscode/
14 |
15 | # build tools
16 | node_modules/
17 |
18 | # logfiles
19 | *.log
20 | .idea/
21 |
22 | # dev artifacts
23 | yarn.lock
24 | package-lock.json
25 |
26 | # misc
27 | README.md
28 |
29 | # source maps
30 | *.js.map
31 |
32 | # source files
33 | lib/
34 |
35 | # test projects
36 | test.js
37 | test.png
38 |
39 | # self
40 | .npmignore
41 | .gitignore
42 |
43 | #example
44 | example/
45 |
46 | #docs
47 | docs/
48 |
49 | #src
50 | src/
51 |
52 | # other configs
53 | webpack.config.js
54 | index.js
55 | index.html
56 | webpack.config.js
57 | build.js
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import promise from './src'
2 |
3 | window.Promise = promise
4 |
5 | function testGenerator () {
6 | const p = new Promise((resolve) => {
7 | setTimeout(() => resolve(`resolve promise`), 2000)
8 | })
9 |
10 | function * f() {
11 | const res = yield p
12 | console.assert(res === 'resolve promise', '[res] is not the expected value')
13 | }
14 |
15 | const g = f()
16 | g.next().value.then(res => g.next(res))
17 | }
18 |
19 | function testAsyncFun () {
20 | function resolve(val) {
21 | return new Promise(resolve => {
22 | setTimeout(() => {
23 | val++
24 | resolve(val)
25 | }, 2000)
26 | })
27 | }
28 |
29 | async function f() {
30 | let val = await resolve(10)
31 | let valTwo = await resolve(val++)
32 |
33 | console.assert(valTwo === 12, '[valTwo] is not the expected value')
34 | }
35 | f()
36 | }
37 |
38 | testGenerator()
39 | testAsyncFun()
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "es2015-promise",
3 | "version": "1.0.3",
4 | "description": "A basic promise implementation",
5 | "main": "dist/promise.common.js",
6 | "module": "dist/promise.esm.js",
7 | "scripts": {
8 | "start": "webpack-dev-server",
9 | "build": "node build.js",
10 | "test": "promises-aplus-tests test.js"
11 | },
12 | "author": "taotao",
13 | "license": "ISC",
14 | "devDependencies": {
15 | "babel-core": "^6.26.3",
16 | "babel-preset-es2015-rollup": "^3.0.0",
17 | "promises-aplus-tests": "*",
18 | "rollup": "^0.62.0",
19 | "rollup-plugin-babel": "^3.0.7",
20 | "rollup-plugin-cleanup": "^3.0.0",
21 | "webpack": "^3.10.0",
22 | "webpack-dev-server": "^2.9.7"
23 | },
24 | "repository": {
25 | "type": "git",
26 | "url": "https://github.com/imtaotao/promise.git"
27 | },
28 | "keywords":[
29 | "promise",
30 | "es6",
31 | "es2015",
32 | "polyfill"
33 | ]
34 | }
35 |
--------------------------------------------------------------------------------
/src/es6_extensions.js:
--------------------------------------------------------------------------------
1 | import Promise from './core'
2 |
3 | Promise.resolve = function (value) {
4 | // 这样实现其实与 es6 规范描述的 promise.resolve 实现是一样的
5 | if (value instanceof Promise) return value
6 |
7 | function valueToPromise (val) {
8 | const p = new Promise(Promise._noop)
9 | p._state = 1
10 | p._value = value
11 |
12 | return p
13 | }
14 |
15 | if (typeof value === 'object' || typeof value === 'function') {
16 | try {
17 | // 如果 value 是一个包含 then 方法的对象
18 | const then = value.then
19 | if (typeof then === 'function') {
20 | return new Promise(then.bind(value))
21 | }
22 | } catch (error) {
23 | return new Promise((_, reject) => { reject(error) })
24 | }
25 | }
26 |
27 | return valueToPromise(value)
28 | }
29 |
30 | Promise.reject = function (reason) {
31 | return new Promise((_, reject) => {
32 | reject(reason)
33 | })
34 | }
35 |
36 | Promise.all = function (array) {
37 | !Array.isArray(array) && (array = Array.from(array))
38 |
39 | return new Promise((resolve, reject) => {
40 | if (array.length === 0) return resolve(array)
41 |
42 | let remaining = array.length
43 | for (let i = 0; i < array.length; i++) {
44 | result(array[i], i)
45 | }
46 |
47 | function result (val, i) {
48 | // 如果 val 是一个正常的值
49 | if (!val || (typeof val !== 'object' && typeof val !== 'function')) {
50 | array[i] = val
51 | --remaining === 0 && resolve(array)
52 | return
53 | }
54 |
55 | // 如果 val 是一个 promise
56 | if (val instanceof Promise && val.then === Promise.prototype.then) {
57 | // 如果是我们自己的 promise 实现,就可以直接根据状态来做
58 | while (val._state === 3) {
59 | val = val._value
60 | }
61 |
62 | if (val._state === 1) return result(val._value, i)
63 | // Promise.all 被拒绝并不影响每个单独的 promise 继续执行
64 | if (val._state === 2) reject(val._value)
65 |
66 | // 为了兼容其他的 promise 实现
67 | val.then(res => result(res, i), reject)
68 | return
69 | }
70 |
71 | // 如果 val 是一个包含 then 方法的对象
72 | if (typeof val.then === 'function') {
73 | const p = new Promise(val.then.bind(val))
74 | p.then(res => result(res, i), reject)
75 | return
76 | }
77 | }
78 | })
79 | }
80 |
81 | Promise.race = function (array) {
82 | return new Promise((resolve, reject) => {
83 | for (const val of array) {
84 | Promise.resolve(val).then(resolve, reject)
85 | }
86 | })
87 | }
--------------------------------------------------------------------------------
/src/async_callback.js:
--------------------------------------------------------------------------------
1 | const capacity = 1024
2 | const queue = []
3 | let index = 0
4 | let flushing = false
5 | let requestFlush
6 | let BrowserMutationObserver
7 |
8 | const isNode = typeof module !== 'undefined' && module.exports
9 |
10 | // MutationObserver
11 | function createMutationObserverCallback (callback) {
12 | let toggle = 1
13 | const observer = new BrowserMutationObserver(callback)
14 | const node = document.createTextNode('')
15 | observer.observe(node, {characterData: true})
16 | return () => {
17 | toggle = -toggle
18 | node.data = toggle
19 | }
20 | }
21 |
22 | // Timer
23 | function createTimerCallback (callback) {
24 | return () => {
25 | let t = setTimeout(handleTimer)
26 |
27 | // 由于 timeout 在 firefox 的 worker 线程中可能会出现 bug
28 | // 为了防止 timeout 不触发,用 interval 预防
29 | let i = setInterval(handleTimer, 50)
30 | function handleTimer () {
31 | clearTimeout(t)
32 | clearInterval(i)
33 | t = null
34 | i = null
35 | callback()
36 | }
37 | }
38 | }
39 |
40 | // node
41 | function setImmediateOrNexttick (callback) {
42 | return () => {
43 | /**
44 | * 由于没有办法真正添加为 microtask,即使在 node 中,promise task 会被添加到 nextTickQueue
45 | * 以下原因导致优先采用 setTmmediate
46 | * 1. 为了保证 promise 最好不能在 nextTick 前面被调用,nextTick 会在 poll 阶段之前被调用
47 | * 2. setTmmediate 会在 poll 阶段结束后被调用,而在 node 中,promise 应用大部分情况都是处理 io
48 | * 3. process.nextTick 递归会导致 event loop 被锁死,而 setImmediate 不会
49 | */
50 | if (flushing && typeof setImmediate === 'function') {
51 | setImmediate(callback)
52 | } else {
53 | process.nextTick(callback)
54 | }
55 | }
56 | }
57 |
58 | if (isNode) {
59 | requestFlush = setImmediateOrNexttick(_requestFlush)
60 | } else {
61 | const scope = typeof global !== 'undefined' ? global : self
62 | BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver
63 |
64 | // MutationObserver 会新建个 microtask,与 promise 最契合
65 | // 备用选择 timeout
66 | requestFlush = typeof BrowserMutationObserver === 'function'
67 | ? createMutationObserverCallback(_requestFlush)
68 | : createTimerCallback(_requestFlush)
69 | }
70 |
71 | function _requestFlush () {
72 | while (index < queue.length) {
73 | const currentIndex = index
74 |
75 | index++
76 | queue[currentIndex].call()
77 |
78 | // 因为 task 里面可能继续添加队列,可能会产生一个无限长的队列,内存爆炸,
79 | // 所以如果大于限定的值,需要做处理
80 | if (index > capacity) {
81 | const newLength = queque.length - index
82 | // 把队列后面的 task 全部移到前面,然后把后面的删掉,从头继续开始便利调用
83 | for (let i = 0; i < newLength; i++) {
84 | queue[i] = queue[index + i]
85 | }
86 |
87 | queue.length -= index
88 | index = 0
89 | }
90 | }
91 |
92 | // 遍历完成后,清空
93 | queue.length = 0
94 | index = 0
95 | flushing = false
96 | }
97 |
98 | export default function ascb(task) {
99 | // 如果 queue 为空,会走 requestFlush,这个函数为一个异步任务
100 | // 而此方法为同步代码,所以等遍历 queue 的时候,队列里面是已经存在 task 了的
101 | // 这样做的好处,如果在异步回调执行之前(requestFlush)有多个 promise
102 | // 会在一次异步任务中被处理,而不是多次新建异步任务
103 | if (!queue.length) {
104 | requestFlush()
105 | flushing = true
106 | }
107 |
108 | queue[queue.length] = task
109 | }
--------------------------------------------------------------------------------
/src/core.js:
--------------------------------------------------------------------------------
1 | // States: 0 - pending, 1 - fulfilled, 2 - rejected, 3 - another promise
2 | import ascb from './async_callback'
3 | const noop = () => {}
4 |
5 | export default class Promise {
6 | constructor (fun) {
7 | if (!(this instanceof Promise)) {
8 | throw TypeError('Calling a Promise constructor without new is forbidden')
9 | }
10 | if (typeof fun !== 'function') {
11 | throw TypeError("Promise constructor's argument must be a function")
12 | }
13 |
14 | this._state = 0
15 | this._value = null
16 | this._deferreds = null
17 |
18 | if (fun === noop) return
19 | doResolve(fun, this)
20 | }
21 |
22 | /**
23 | * 本来 prototype method 应该需要判断 this,
24 | * 如果 this 不符合要求应该 throw TypeError,
25 | * example:
26 | * const { then } = promise.then
27 | * then(f, r) // TypeError: ...
28 | */
29 | then (onFulfilled, onRejected) {
30 | /**
31 | * 每次都会返回一个新的 promise 出去
32 | * 而当前上下文会有个 deferred 队列
33 | * 每个 deferred 都会保存这个 return 出去的 promise 和回调
34 | */
35 | const p = new Promise(noop)
36 | handle(this, new Handler(p, onFulfilled, onRejected))
37 |
38 | return p
39 | }
40 |
41 | catch (onRejected) {
42 | return this.then(null, onRejected)
43 | }
44 |
45 | finally (fun) {
46 | // 我们要保证 fun 不会收到任何参数(正常或者错误的值)
47 | // 用 Promise.resolve 包裹起来的原因是,fun 有可能返回的是一个 promise,我们要保证 finally 之后继续链式
48 | return this.then(
49 | value => Promise.resolve(fun()).then(() => value),
50 | reason => Promise.resolve(fun()).then(() => { throw reason })
51 | )
52 | }
53 |
54 | getValue () {
55 | if (this._state === 3) {
56 | return this._value.getValue()
57 | }
58 |
59 | return this._value
60 | }
61 |
62 | toString () {
63 | return '[object Promise]'
64 | }
65 | }
66 |
67 | Promise._noop = noop
68 |
69 | function doResolve (fun, promise) {
70 | let done = false
71 |
72 | // 立个 flag 保证不能重复调用 resolve 或者 reject
73 | // 因为 promise 的 state 一旦改变,就再也不可能改变了
74 | function _resolve (value) {
75 | if (done) return
76 | done = true
77 | resolve(promise, value)
78 | }
79 |
80 | function _reject (reason) {
81 | if (done) return
82 | done = true
83 | reject(promise, reason)
84 | }
85 |
86 | try {
87 | fun(_resolve, _reject)
88 | } catch (error) {
89 | _reject(error)
90 | }
91 | }
92 |
93 | function resolve (promise, newValue) {
94 | // 规范关于 resolve 的描述 https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
95 | /**
96 | * newValue 有可能有以下几种情况
97 | * 1. 当前上下文自己,这种情况直接报个错
98 | * 2. object 或者 function
99 | * 这种情况需要去尝试那 newValue 的 then 方法
100 | * 如果拿不到,那就代表是个正常的对象或者函数
101 | * a. 如果 newValue 是一个新的 promise,需要根据新的 promise 的 state 来更改,此时当前 promise 的 state 为 3
102 | * b. 如果 newValue 是带 then 方法的对象({ then () {} }),
103 | * 需要把这个 then 方法当成 promise 的构造函数的参数进行调用(可以在浏览器控制台用原生 promise 的测试下)
104 | * 3. 其他的值,state 改为 1
105 | */
106 | if (promise === newValue) {
107 | reject(promise, new TypeError('A promise cannot be resolved with itself'))
108 | return
109 | }
110 |
111 | // 如果 newValue 是个对象或者函数
112 | if (
113 | newValue &&
114 | (typeof newValue === 'object' || typeof newValue === 'function')
115 | ) {
116 | // 尝试去拿到 newValue 的 then 方法,如果失败 then 方法会是一个 error
117 | const [isError, then] = getThen(newValue)
118 | if (isError) {
119 | reject(promise, then)
120 | return
121 | }
122 |
123 | // 如果 newValue 是一个 Promise 实例的话,state 为 3
124 | if (then === promise.then && newValue instanceof Promise) {
125 | promise._state = 3
126 | promise._value = newValue
127 | finale(promise)
128 | return
129 | } else if (typeof then === 'function') {
130 | // 修复 then 方法内部的 this 指向
131 | doResolve(then.bind(newValue), promise)
132 | return
133 | }
134 | }
135 |
136 | promise._state = 1
137 | promise._value = newValue
138 | finale(promise)
139 | }
140 |
141 | function reject (promise, reason) {
142 | // 改变 state 和 value
143 | promise._state = 2
144 | promise._value = reason
145 | finale(promise)
146 | }
147 |
148 | function finale (promise) {
149 | /**
150 | * 1.如果当前 promise 没有 deferreds,代表 resolve 是通过同步进行调用的
151 | * 此时 promise 的 state 已经改变,value 也已经拿到,不需要做什么事情
152 | * 2.如果 deferreds 是存在的,就需要对每个 deferreds 进行处理
153 | */
154 | if (promise._deferreds) {
155 | if (promise._deferreds.length === 1) {
156 | handle(promise, promise._deferreds[0])
157 | promise._deferreds = null
158 | return
159 | }
160 |
161 | for (const deferred of promise._deferreds) {
162 | handle(promise, deferred)
163 | }
164 | promise._deferreds = null
165 | }
166 | }
167 |
168 | /**
169 | * handle 方法供两个接口调用,finale 和 then
170 | * 它也提供了两种功能,对传进来的 promise 添加 deferred 或者 调用 deferred 的回调
171 | */
172 | function handle (promise, deferred) {
173 | /**
174 | * 如果 promise 的 state 为 3,拿到最底层的 promise
175 | * 因为需要把 deferred 转移到最底层的 promise 上
176 | * 这样当前上下文(promise)添加的 then 就会随着最底层的 promise 的 state 改变而改变
177 | */
178 | while (promise._state === 3) {
179 | promise = promise._value
180 | }
181 |
182 | /**
183 | * 如果通过 then 方法走到这里,一般情况下 state 都为 0,除非 resolve 为同步代码
184 | * 如果通过 finale 方法走到这里,state 肯定 1 或者 2,出发经过了 while 循环,底层的 promise 状态还为 0
185 | */
186 | if (promise._state === 0) {
187 | promise._deferreds
188 | ? promise._deferreds.push(deferred)
189 | : (promise._deferreds = [deferred])
190 | return
191 | }
192 |
193 | /**
194 | * 1.如果是通过 finale 走到这里
195 | * 此时 promise.state 为 1 或者 2
196 | * 2.如果是通过 then 方法走到这里
197 | * 此时 promise.state 为 1 或者 2,promise.deferred 为 null
198 | * 但是可以直接用 handle 参数(promise, deferred)进行调用
199 | */
200 | handleResolved(promise, deferred)
201 | }
202 |
203 | function handleResolved (promise, deferred) {
204 | // 异步调用,优先通过微任务调用
205 | ascb(() => {
206 | const isResolve = promise._state === 1
207 | const callback = deferred[isResolve ? 'onFulfilled' : 'onRejected']
208 |
209 | // 如果当期 deferred 的回调为 null 就把当前 promise._value 为值继续往下找
210 | if (callback === null) {
211 | isResolve
212 | ? resolve(deferred.promise, promise._value)
213 | : reject(deferred.promise, promise._value)
214 | return
215 | }
216 |
217 | try {
218 | /**
219 | * 如果外面是 then 形式的链式调用,此时的 deferred.promise 应该是
220 | * {
221 | * deferred: [不为空的数组],
222 | * state: 0,
223 | * value: null,
224 | * }
225 | */
226 | const result = callback(promise._value)
227 |
228 | /**
229 | * 经过 resolve 之后,deferred.promise 应该是
230 | * {
231 | * deferred: [不为空的数组],
232 | * state: 1 或者 2 或者 3,
233 | * value: xx
234 | * }
235 | * 然后走 finale 就可以完成链式操作了
236 | */
237 | resolve(deferred.promise, result)
238 | } catch (error) {
239 | reject(deferred.promise, error)
240 | }
241 | })
242 | }
243 |
244 | function getThen (value) {
245 | try {
246 | return [false, value.then]
247 | } catch (error) {
248 | return [true, error]
249 | }
250 | }
251 |
252 | // 一个 deferred 对象应该为 { promise, onFulfilled, onRejected }
253 | function Handler (promise, onFulfilled, onRejected) {
254 | this.promise = promise
255 | this.onFulfilled = typeof onFulfilled === 'function'
256 | ? onFulfilled
257 | : null
258 | this.onRejected = typeof onRejected === 'function'
259 | ? onRejected
260 | : null
261 | }
--------------------------------------------------------------------------------
/dist/promise.esm.js:
--------------------------------------------------------------------------------
1 | var capacity = 1024;
2 | var queue = [];
3 | var index = 0;
4 | var flushing = false;
5 | var requestFlush = void 0;
6 | var BrowserMutationObserver = void 0;
7 | var isNode = typeof module !== 'undefined' && module.exports;
8 | function createMutationObserverCallback(callback) {
9 | var toggle = 1;
10 | var observer = new BrowserMutationObserver(callback);
11 | var node = document.createTextNode('');
12 | observer.observe(node, { characterData: true });
13 | return function () {
14 | toggle = -toggle;
15 | node.data = toggle;
16 | };
17 | }
18 | function createTimerCallback(callback) {
19 | return function () {
20 | var t = setTimeout(handleTimer);
21 | var i = setInterval(handleTimer, 50);
22 | function handleTimer() {
23 | clearTimeout(t);
24 | clearInterval(i);
25 | t = null;
26 | i = null;
27 | callback();
28 | }
29 | };
30 | }
31 | function setImmediateOrNexttick(callback) {
32 | return function () {
33 | if (flushing && typeof setImmediate === 'function') {
34 | setImmediate(callback);
35 | } else {
36 | process.nextTick(callback);
37 | }
38 | };
39 | }
40 | if (isNode) {
41 | requestFlush = setImmediateOrNexttick(_requestFlush);
42 | } else {
43 | var scope = typeof global !== 'undefined' ? global : self;
44 | BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver;
45 | requestFlush = typeof BrowserMutationObserver === 'function' ? createMutationObserverCallback(_requestFlush) : createTimerCallback(_requestFlush);
46 | }
47 | function _requestFlush() {
48 | while (index < queue.length) {
49 | var currentIndex = index;
50 | index++;
51 | queue[currentIndex].call();
52 | if (index > capacity) {
53 | var newLength = queque.length - index;
54 | for (var i = 0; i < newLength; i++) {
55 | queue[i] = queue[index + i];
56 | }
57 | queue.length -= index;
58 | index = 0;
59 | }
60 | }
61 | queue.length = 0;
62 | index = 0;
63 | flushing = false;
64 | }
65 | function ascb(task) {
66 | if (!queue.length) {
67 | requestFlush();
68 | flushing = true;
69 | }
70 | queue[queue.length] = task;
71 | }
72 |
73 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
74 | return typeof obj;
75 | } : function (obj) {
76 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
77 | };
78 |
79 | var classCallCheck = function (instance, Constructor) {
80 | if (!(instance instanceof Constructor)) {
81 | throw new TypeError("Cannot call a class as a function");
82 | }
83 | };
84 |
85 | var createClass = function () {
86 | function defineProperties(target, props) {
87 | for (var i = 0; i < props.length; i++) {
88 | var descriptor = props[i];
89 | descriptor.enumerable = descriptor.enumerable || false;
90 | descriptor.configurable = true;
91 | if ("value" in descriptor) descriptor.writable = true;
92 | Object.defineProperty(target, descriptor.key, descriptor);
93 | }
94 | }
95 |
96 | return function (Constructor, protoProps, staticProps) {
97 | if (protoProps) defineProperties(Constructor.prototype, protoProps);
98 | if (staticProps) defineProperties(Constructor, staticProps);
99 | return Constructor;
100 | };
101 | }();
102 |
103 | var slicedToArray = function () {
104 | function sliceIterator(arr, i) {
105 | var _arr = [];
106 | var _n = true;
107 | var _d = false;
108 | var _e = undefined;
109 |
110 | try {
111 | for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
112 | _arr.push(_s.value);
113 |
114 | if (i && _arr.length === i) break;
115 | }
116 | } catch (err) {
117 | _d = true;
118 | _e = err;
119 | } finally {
120 | try {
121 | if (!_n && _i["return"]) _i["return"]();
122 | } finally {
123 | if (_d) throw _e;
124 | }
125 | }
126 |
127 | return _arr;
128 | }
129 |
130 | return function (arr, i) {
131 | if (Array.isArray(arr)) {
132 | return arr;
133 | } else if (Symbol.iterator in Object(arr)) {
134 | return sliceIterator(arr, i);
135 | } else {
136 | throw new TypeError("Invalid attempt to destructure non-iterable instance");
137 | }
138 | };
139 | }();
140 |
141 | var noop = function noop() {};
142 |
143 | var Promise$1 = function () {
144 | function Promise(fun) {
145 | classCallCheck(this, Promise);
146 |
147 | if (!(this instanceof Promise)) {
148 | throw TypeError('Calling a Promise constructor without new is forbidden');
149 | }
150 | if (typeof fun !== 'function') {
151 | throw TypeError("Promise constructor's argument must be a function");
152 | }
153 | this._state = 0;
154 | this._value = null;
155 | this._deferreds = null;
156 | if (fun === noop) return;
157 | doResolve(fun, this);
158 | }
159 |
160 | createClass(Promise, [{
161 | key: 'then',
162 | value: function then(onFulfilled, onRejected) {
163 | var p = new Promise(noop);
164 | handle(this, new Handler(p, onFulfilled, onRejected));
165 | return p;
166 | }
167 | }, {
168 | key: 'catch',
169 | value: function _catch(onRejected) {
170 | return this.then(null, onRejected);
171 | }
172 | }, {
173 | key: 'finally',
174 | value: function _finally(fun) {
175 | return this.then(function (value) {
176 | return Promise.resolve(fun()).then(function () {
177 | return value;
178 | });
179 | }, function (reason) {
180 | return Promise.resolve(fun()).then(function () {
181 | throw reason;
182 | });
183 | });
184 | }
185 | }, {
186 | key: 'getValue',
187 | value: function getValue() {
188 | if (this._state === 3) {
189 | return this._value.getValue();
190 | }
191 | return this._value;
192 | }
193 | }, {
194 | key: 'toString',
195 | value: function toString() {
196 | return '[object Promise]';
197 | }
198 | }]);
199 | return Promise;
200 | }();
201 |
202 | Promise$1._noop = noop;
203 | function doResolve(fun, promise) {
204 | var done = false;
205 | function _resolve(value) {
206 | if (done) return;
207 | done = true;
208 | resolve(promise, value);
209 | }
210 | function _reject(reason) {
211 | if (done) return;
212 | done = true;
213 | reject(promise, reason);
214 | }
215 | try {
216 | fun(_resolve, _reject);
217 | } catch (error) {
218 | _reject(error);
219 | }
220 | }
221 | function resolve(promise, newValue) {
222 | if (promise === newValue) {
223 | reject(promise, new TypeError('A promise cannot be resolved with itself'));
224 | return;
225 | }
226 | if (newValue && ((typeof newValue === 'undefined' ? 'undefined' : _typeof(newValue)) === 'object' || typeof newValue === 'function')) {
227 | var _getThen = getThen(newValue),
228 | _getThen2 = slicedToArray(_getThen, 2),
229 | isError = _getThen2[0],
230 | then = _getThen2[1];
231 |
232 | if (isError) {
233 | reject(promise, then);
234 | return;
235 | }
236 | if (then === promise.then && newValue instanceof Promise$1) {
237 | promise._state = 3;
238 | promise._value = newValue;
239 | finale(promise);
240 | return;
241 | } else if (typeof then === 'function') {
242 | doResolve(then.bind(newValue), promise);
243 | return;
244 | }
245 | }
246 | promise._state = 1;
247 | promise._value = newValue;
248 | finale(promise);
249 | }
250 | function reject(promise, reason) {
251 | promise._state = 2;
252 | promise._value = reason;
253 | finale(promise);
254 | }
255 | function finale(promise) {
256 | if (promise._deferreds) {
257 | if (promise._deferreds.length === 1) {
258 | handle(promise, promise._deferreds[0]);
259 | promise._deferreds = null;
260 | return;
261 | }
262 | var _iteratorNormalCompletion = true;
263 | var _didIteratorError = false;
264 | var _iteratorError = undefined;
265 |
266 | try {
267 | for (var _iterator = promise._deferreds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
268 | var deferred = _step.value;
269 |
270 | handle(promise, deferred);
271 | }
272 | } catch (err) {
273 | _didIteratorError = true;
274 | _iteratorError = err;
275 | } finally {
276 | try {
277 | if (!_iteratorNormalCompletion && _iterator.return) {
278 | _iterator.return();
279 | }
280 | } finally {
281 | if (_didIteratorError) {
282 | throw _iteratorError;
283 | }
284 | }
285 | }
286 |
287 | promise._deferreds = null;
288 | }
289 | }
290 | function handle(promise, deferred) {
291 | while (promise._state === 3) {
292 | promise = promise._value;
293 | }
294 | if (promise._state === 0) {
295 | promise._deferreds ? promise._deferreds.push(deferred) : promise._deferreds = [deferred];
296 | return;
297 | }
298 | handleResolved(promise, deferred);
299 | }
300 | function handleResolved(promise, deferred) {
301 | ascb(function () {
302 | var isResolve = promise._state === 1;
303 | var callback = deferred[isResolve ? 'onFulfilled' : 'onRejected'];
304 | if (callback === null) {
305 | isResolve ? resolve(deferred.promise, promise._value) : reject(deferred.promise, promise._value);
306 | return;
307 | }
308 | try {
309 | var result = callback(promise._value);
310 | resolve(deferred.promise, result);
311 | } catch (error) {
312 | reject(deferred.promise, error);
313 | }
314 | });
315 | }
316 | function getThen(value) {
317 | try {
318 | return [false, value.then];
319 | } catch (error) {
320 | return [true, error];
321 | }
322 | }
323 | function Handler(promise, onFulfilled, onRejected) {
324 | this.promise = promise;
325 | this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
326 | this.onRejected = typeof onRejected === 'function' ? onRejected : null;
327 | }
328 |
329 | Promise$1.resolve = function (value) {
330 | if (value instanceof Promise$1) return value;
331 | function valueToPromise(val) {
332 | var p = new Promise$1(Promise$1._noop);
333 | p._state = 1;
334 | p._value = value;
335 | return p;
336 | }
337 | if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' || typeof value === 'function') {
338 | try {
339 | var then = value.then;
340 | if (typeof then === 'function') {
341 | return new Promise$1(then.bind(value));
342 | }
343 | } catch (error) {
344 | return new Promise$1(function (_, reject) {
345 | reject(error);
346 | });
347 | }
348 | }
349 | return valueToPromise(value);
350 | };
351 | Promise$1.reject = function (reason) {
352 | return new Promise$1(function (_, reject) {
353 | reject(reason);
354 | });
355 | };
356 | Promise$1.all = function (array) {
357 | !Array.isArray(array) && (array = Array.from(array));
358 | return new Promise$1(function (resolve, reject) {
359 | if (array.length === 0) return resolve(array);
360 | var remaining = array.length;
361 | for (var i = 0; i < array.length; i++) {
362 | result(array[i], i);
363 | }
364 | function result(val, i) {
365 | if (!val || (typeof val === 'undefined' ? 'undefined' : _typeof(val)) !== 'object' && typeof val !== 'function') {
366 | array[i] = val;
367 | --remaining === 0 && resolve(array);
368 | return;
369 | }
370 | if (val instanceof Promise$1 && val.then === Promise$1.prototype.then) {
371 | while (val._state === 3) {
372 | val = val._value;
373 | }
374 | if (val._state === 1) return result(val._value, i);
375 | if (val._state === 2) reject(val._value);
376 | val.then(function (res) {
377 | return result(res, i);
378 | }, reject);
379 | return;
380 | }
381 | if (typeof val.then === 'function') {
382 | var p = new Promise$1(val.then.bind(val));
383 | p.then(function (res) {
384 | return result(res, i);
385 | }, reject);
386 | return;
387 | }
388 | }
389 | });
390 | };
391 | Promise$1.race = function (array) {
392 | return new Promise$1(function (resolve, reject) {
393 | var _iteratorNormalCompletion = true;
394 | var _didIteratorError = false;
395 | var _iteratorError = undefined;
396 |
397 | try {
398 | for (var _iterator = array[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
399 | var val = _step.value;
400 |
401 | Promise$1.resolve(val).then(resolve, reject);
402 | }
403 | } catch (err) {
404 | _didIteratorError = true;
405 | _iteratorError = err;
406 | } finally {
407 | try {
408 | if (!_iteratorNormalCompletion && _iterator.return) {
409 | _iterator.return();
410 | }
411 | } finally {
412 | if (_didIteratorError) {
413 | throw _iteratorError;
414 | }
415 | }
416 | }
417 | });
418 | };
419 |
420 | export default Promise$1;
421 |
--------------------------------------------------------------------------------
/dist/promise.common.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var capacity = 1024;
4 | var queue = [];
5 | var index = 0;
6 | var flushing = false;
7 | var requestFlush = void 0;
8 | var BrowserMutationObserver = void 0;
9 | var isNode = typeof module !== 'undefined' && module.exports;
10 | function createMutationObserverCallback(callback) {
11 | var toggle = 1;
12 | var observer = new BrowserMutationObserver(callback);
13 | var node = document.createTextNode('');
14 | observer.observe(node, { characterData: true });
15 | return function () {
16 | toggle = -toggle;
17 | node.data = toggle;
18 | };
19 | }
20 | function createTimerCallback(callback) {
21 | return function () {
22 | var t = setTimeout(handleTimer);
23 | var i = setInterval(handleTimer, 50);
24 | function handleTimer() {
25 | clearTimeout(t);
26 | clearInterval(i);
27 | t = null;
28 | i = null;
29 | callback();
30 | }
31 | };
32 | }
33 | function setImmediateOrNexttick(callback) {
34 | return function () {
35 | if (flushing && typeof setImmediate === 'function') {
36 | setImmediate(callback);
37 | } else {
38 | process.nextTick(callback);
39 | }
40 | };
41 | }
42 | if (isNode) {
43 | requestFlush = setImmediateOrNexttick(_requestFlush);
44 | } else {
45 | var scope = typeof global !== 'undefined' ? global : self;
46 | BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver;
47 | requestFlush = typeof BrowserMutationObserver === 'function' ? createMutationObserverCallback(_requestFlush) : createTimerCallback(_requestFlush);
48 | }
49 | function _requestFlush() {
50 | while (index < queue.length) {
51 | var currentIndex = index;
52 | index++;
53 | queue[currentIndex].call();
54 | if (index > capacity) {
55 | var newLength = queque.length - index;
56 | for (var i = 0; i < newLength; i++) {
57 | queue[i] = queue[index + i];
58 | }
59 | queue.length -= index;
60 | index = 0;
61 | }
62 | }
63 | queue.length = 0;
64 | index = 0;
65 | flushing = false;
66 | }
67 | function ascb(task) {
68 | if (!queue.length) {
69 | requestFlush();
70 | flushing = true;
71 | }
72 | queue[queue.length] = task;
73 | }
74 |
75 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
76 | return typeof obj;
77 | } : function (obj) {
78 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
79 | };
80 |
81 | var classCallCheck = function (instance, Constructor) {
82 | if (!(instance instanceof Constructor)) {
83 | throw new TypeError("Cannot call a class as a function");
84 | }
85 | };
86 |
87 | var createClass = function () {
88 | function defineProperties(target, props) {
89 | for (var i = 0; i < props.length; i++) {
90 | var descriptor = props[i];
91 | descriptor.enumerable = descriptor.enumerable || false;
92 | descriptor.configurable = true;
93 | if ("value" in descriptor) descriptor.writable = true;
94 | Object.defineProperty(target, descriptor.key, descriptor);
95 | }
96 | }
97 |
98 | return function (Constructor, protoProps, staticProps) {
99 | if (protoProps) defineProperties(Constructor.prototype, protoProps);
100 | if (staticProps) defineProperties(Constructor, staticProps);
101 | return Constructor;
102 | };
103 | }();
104 |
105 | var slicedToArray = function () {
106 | function sliceIterator(arr, i) {
107 | var _arr = [];
108 | var _n = true;
109 | var _d = false;
110 | var _e = undefined;
111 |
112 | try {
113 | for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
114 | _arr.push(_s.value);
115 |
116 | if (i && _arr.length === i) break;
117 | }
118 | } catch (err) {
119 | _d = true;
120 | _e = err;
121 | } finally {
122 | try {
123 | if (!_n && _i["return"]) _i["return"]();
124 | } finally {
125 | if (_d) throw _e;
126 | }
127 | }
128 |
129 | return _arr;
130 | }
131 |
132 | return function (arr, i) {
133 | if (Array.isArray(arr)) {
134 | return arr;
135 | } else if (Symbol.iterator in Object(arr)) {
136 | return sliceIterator(arr, i);
137 | } else {
138 | throw new TypeError("Invalid attempt to destructure non-iterable instance");
139 | }
140 | };
141 | }();
142 |
143 | var noop = function noop() {};
144 |
145 | var Promise$1 = function () {
146 | function Promise(fun) {
147 | classCallCheck(this, Promise);
148 |
149 | if (!(this instanceof Promise)) {
150 | throw TypeError('Calling a Promise constructor without new is forbidden');
151 | }
152 | if (typeof fun !== 'function') {
153 | throw TypeError("Promise constructor's argument must be a function");
154 | }
155 | this._state = 0;
156 | this._value = null;
157 | this._deferreds = null;
158 | if (fun === noop) return;
159 | doResolve(fun, this);
160 | }
161 |
162 | createClass(Promise, [{
163 | key: 'then',
164 | value: function then(onFulfilled, onRejected) {
165 | var p = new Promise(noop);
166 | handle(this, new Handler(p, onFulfilled, onRejected));
167 | return p;
168 | }
169 | }, {
170 | key: 'catch',
171 | value: function _catch(onRejected) {
172 | return this.then(null, onRejected);
173 | }
174 | }, {
175 | key: 'finally',
176 | value: function _finally(fun) {
177 | return this.then(function (value) {
178 | return Promise.resolve(fun()).then(function () {
179 | return value;
180 | });
181 | }, function (reason) {
182 | return Promise.resolve(fun()).then(function () {
183 | throw reason;
184 | });
185 | });
186 | }
187 | }, {
188 | key: 'getValue',
189 | value: function getValue() {
190 | if (this._state === 3) {
191 | return this._value.getValue();
192 | }
193 | return this._value;
194 | }
195 | }, {
196 | key: 'toString',
197 | value: function toString() {
198 | return '[object Promise]';
199 | }
200 | }]);
201 | return Promise;
202 | }();
203 |
204 | Promise$1._noop = noop;
205 | function doResolve(fun, promise) {
206 | var done = false;
207 | function _resolve(value) {
208 | if (done) return;
209 | done = true;
210 | resolve(promise, value);
211 | }
212 | function _reject(reason) {
213 | if (done) return;
214 | done = true;
215 | reject(promise, reason);
216 | }
217 | try {
218 | fun(_resolve, _reject);
219 | } catch (error) {
220 | _reject(error);
221 | }
222 | }
223 | function resolve(promise, newValue) {
224 | if (promise === newValue) {
225 | reject(promise, new TypeError('A promise cannot be resolved with itself'));
226 | return;
227 | }
228 | if (newValue && ((typeof newValue === 'undefined' ? 'undefined' : _typeof(newValue)) === 'object' || typeof newValue === 'function')) {
229 | var _getThen = getThen(newValue),
230 | _getThen2 = slicedToArray(_getThen, 2),
231 | isError = _getThen2[0],
232 | then = _getThen2[1];
233 |
234 | if (isError) {
235 | reject(promise, then);
236 | return;
237 | }
238 | if (then === promise.then && newValue instanceof Promise$1) {
239 | promise._state = 3;
240 | promise._value = newValue;
241 | finale(promise);
242 | return;
243 | } else if (typeof then === 'function') {
244 | doResolve(then.bind(newValue), promise);
245 | return;
246 | }
247 | }
248 | promise._state = 1;
249 | promise._value = newValue;
250 | finale(promise);
251 | }
252 | function reject(promise, reason) {
253 | promise._state = 2;
254 | promise._value = reason;
255 | finale(promise);
256 | }
257 | function finale(promise) {
258 | if (promise._deferreds) {
259 | if (promise._deferreds.length === 1) {
260 | handle(promise, promise._deferreds[0]);
261 | promise._deferreds = null;
262 | return;
263 | }
264 | var _iteratorNormalCompletion = true;
265 | var _didIteratorError = false;
266 | var _iteratorError = undefined;
267 |
268 | try {
269 | for (var _iterator = promise._deferreds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
270 | var deferred = _step.value;
271 |
272 | handle(promise, deferred);
273 | }
274 | } catch (err) {
275 | _didIteratorError = true;
276 | _iteratorError = err;
277 | } finally {
278 | try {
279 | if (!_iteratorNormalCompletion && _iterator.return) {
280 | _iterator.return();
281 | }
282 | } finally {
283 | if (_didIteratorError) {
284 | throw _iteratorError;
285 | }
286 | }
287 | }
288 |
289 | promise._deferreds = null;
290 | }
291 | }
292 | function handle(promise, deferred) {
293 | while (promise._state === 3) {
294 | promise = promise._value;
295 | }
296 | if (promise._state === 0) {
297 | promise._deferreds ? promise._deferreds.push(deferred) : promise._deferreds = [deferred];
298 | return;
299 | }
300 | handleResolved(promise, deferred);
301 | }
302 | function handleResolved(promise, deferred) {
303 | ascb(function () {
304 | var isResolve = promise._state === 1;
305 | var callback = deferred[isResolve ? 'onFulfilled' : 'onRejected'];
306 | if (callback === null) {
307 | isResolve ? resolve(deferred.promise, promise._value) : reject(deferred.promise, promise._value);
308 | return;
309 | }
310 | try {
311 | var result = callback(promise._value);
312 | resolve(deferred.promise, result);
313 | } catch (error) {
314 | reject(deferred.promise, error);
315 | }
316 | });
317 | }
318 | function getThen(value) {
319 | try {
320 | return [false, value.then];
321 | } catch (error) {
322 | return [true, error];
323 | }
324 | }
325 | function Handler(promise, onFulfilled, onRejected) {
326 | this.promise = promise;
327 | this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
328 | this.onRejected = typeof onRejected === 'function' ? onRejected : null;
329 | }
330 |
331 | Promise$1.resolve = function (value) {
332 | if (value instanceof Promise$1) return value;
333 | function valueToPromise(val) {
334 | var p = new Promise$1(Promise$1._noop);
335 | p._state = 1;
336 | p._value = value;
337 | return p;
338 | }
339 | if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' || typeof value === 'function') {
340 | try {
341 | var then = value.then;
342 | if (typeof then === 'function') {
343 | return new Promise$1(then.bind(value));
344 | }
345 | } catch (error) {
346 | return new Promise$1(function (_, reject) {
347 | reject(error);
348 | });
349 | }
350 | }
351 | return valueToPromise(value);
352 | };
353 | Promise$1.reject = function (reason) {
354 | return new Promise$1(function (_, reject) {
355 | reject(reason);
356 | });
357 | };
358 | Promise$1.all = function (array) {
359 | !Array.isArray(array) && (array = Array.from(array));
360 | return new Promise$1(function (resolve, reject) {
361 | if (array.length === 0) return resolve(array);
362 | var remaining = array.length;
363 | for (var i = 0; i < array.length; i++) {
364 | result(array[i], i);
365 | }
366 | function result(val, i) {
367 | if (!val || (typeof val === 'undefined' ? 'undefined' : _typeof(val)) !== 'object' && typeof val !== 'function') {
368 | array[i] = val;
369 | --remaining === 0 && resolve(array);
370 | return;
371 | }
372 | if (val instanceof Promise$1 && val.then === Promise$1.prototype.then) {
373 | while (val._state === 3) {
374 | val = val._value;
375 | }
376 | if (val._state === 1) return result(val._value, i);
377 | if (val._state === 2) reject(val._value);
378 | val.then(function (res) {
379 | return result(res, i);
380 | }, reject);
381 | return;
382 | }
383 | if (typeof val.then === 'function') {
384 | var p = new Promise$1(val.then.bind(val));
385 | p.then(function (res) {
386 | return result(res, i);
387 | }, reject);
388 | return;
389 | }
390 | }
391 | });
392 | };
393 | Promise$1.race = function (array) {
394 | return new Promise$1(function (resolve, reject) {
395 | var _iteratorNormalCompletion = true;
396 | var _didIteratorError = false;
397 | var _iteratorError = undefined;
398 |
399 | try {
400 | for (var _iterator = array[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
401 | var val = _step.value;
402 |
403 | Promise$1.resolve(val).then(resolve, reject);
404 | }
405 | } catch (err) {
406 | _didIteratorError = true;
407 | _iteratorError = err;
408 | } finally {
409 | try {
410 | if (!_iteratorNormalCompletion && _iterator.return) {
411 | _iterator.return();
412 | }
413 | } finally {
414 | if (_didIteratorError) {
415 | throw _iteratorError;
416 | }
417 | }
418 | }
419 | });
420 | };
421 |
422 | module.exports = Promise$1;
423 |
--------------------------------------------------------------------------------
/dist/promise.min.js:
--------------------------------------------------------------------------------
1 | (function (global, factory) {
2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3 | typeof define === 'function' && define.amd ? define(factory) :
4 | (global.Promise = factory());
5 | }(this, (function () { 'use strict';
6 |
7 | var capacity = 1024;
8 | var queue = [];
9 | var index = 0;
10 | var flushing = false;
11 | var requestFlush = void 0;
12 | var BrowserMutationObserver = void 0;
13 | var isNode = typeof module !== 'undefined' && module.exports;
14 | function createMutationObserverCallback(callback) {
15 | var toggle = 1;
16 | var observer = new BrowserMutationObserver(callback);
17 | var node = document.createTextNode('');
18 | observer.observe(node, { characterData: true });
19 | return function () {
20 | toggle = -toggle;
21 | node.data = toggle;
22 | };
23 | }
24 | function createTimerCallback(callback) {
25 | return function () {
26 | var t = setTimeout(handleTimer);
27 | var i = setInterval(handleTimer, 50);
28 | function handleTimer() {
29 | clearTimeout(t);
30 | clearInterval(i);
31 | t = null;
32 | i = null;
33 | callback();
34 | }
35 | };
36 | }
37 | function setImmediateOrNexttick(callback) {
38 | return function () {
39 | if (flushing && typeof setImmediate === 'function') {
40 | setImmediate(callback);
41 | } else {
42 | process.nextTick(callback);
43 | }
44 | };
45 | }
46 | if (isNode) {
47 | requestFlush = setImmediateOrNexttick(_requestFlush);
48 | } else {
49 | var scope = typeof global !== 'undefined' ? global : self;
50 | BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver;
51 | requestFlush = typeof BrowserMutationObserver === 'function' ? createMutationObserverCallback(_requestFlush) : createTimerCallback(_requestFlush);
52 | }
53 | function _requestFlush() {
54 | while (index < queue.length) {
55 | var currentIndex = index;
56 | index++;
57 | queue[currentIndex].call();
58 | if (index > capacity) {
59 | var newLength = queque.length - index;
60 | for (var i = 0; i < newLength; i++) {
61 | queue[i] = queue[index + i];
62 | }
63 | queue.length -= index;
64 | index = 0;
65 | }
66 | }
67 | queue.length = 0;
68 | index = 0;
69 | flushing = false;
70 | }
71 | function ascb(task) {
72 | if (!queue.length) {
73 | requestFlush();
74 | flushing = true;
75 | }
76 | queue[queue.length] = task;
77 | }
78 |
79 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
80 | return typeof obj;
81 | } : function (obj) {
82 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
83 | };
84 |
85 | var classCallCheck = function (instance, Constructor) {
86 | if (!(instance instanceof Constructor)) {
87 | throw new TypeError("Cannot call a class as a function");
88 | }
89 | };
90 |
91 | var createClass = function () {
92 | function defineProperties(target, props) {
93 | for (var i = 0; i < props.length; i++) {
94 | var descriptor = props[i];
95 | descriptor.enumerable = descriptor.enumerable || false;
96 | descriptor.configurable = true;
97 | if ("value" in descriptor) descriptor.writable = true;
98 | Object.defineProperty(target, descriptor.key, descriptor);
99 | }
100 | }
101 |
102 | return function (Constructor, protoProps, staticProps) {
103 | if (protoProps) defineProperties(Constructor.prototype, protoProps);
104 | if (staticProps) defineProperties(Constructor, staticProps);
105 | return Constructor;
106 | };
107 | }();
108 |
109 | var slicedToArray = function () {
110 | function sliceIterator(arr, i) {
111 | var _arr = [];
112 | var _n = true;
113 | var _d = false;
114 | var _e = undefined;
115 |
116 | try {
117 | for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
118 | _arr.push(_s.value);
119 |
120 | if (i && _arr.length === i) break;
121 | }
122 | } catch (err) {
123 | _d = true;
124 | _e = err;
125 | } finally {
126 | try {
127 | if (!_n && _i["return"]) _i["return"]();
128 | } finally {
129 | if (_d) throw _e;
130 | }
131 | }
132 |
133 | return _arr;
134 | }
135 |
136 | return function (arr, i) {
137 | if (Array.isArray(arr)) {
138 | return arr;
139 | } else if (Symbol.iterator in Object(arr)) {
140 | return sliceIterator(arr, i);
141 | } else {
142 | throw new TypeError("Invalid attempt to destructure non-iterable instance");
143 | }
144 | };
145 | }();
146 |
147 | var noop = function noop() {};
148 |
149 | var Promise$1 = function () {
150 | function Promise(fun) {
151 | classCallCheck(this, Promise);
152 |
153 | if (!(this instanceof Promise)) {
154 | throw TypeError('Calling a Promise constructor without new is forbidden');
155 | }
156 | if (typeof fun !== 'function') {
157 | throw TypeError("Promise constructor's argument must be a function");
158 | }
159 | this._state = 0;
160 | this._value = null;
161 | this._deferreds = null;
162 | if (fun === noop) return;
163 | doResolve(fun, this);
164 | }
165 |
166 | createClass(Promise, [{
167 | key: 'then',
168 | value: function then(onFulfilled, onRejected) {
169 | var p = new Promise(noop);
170 | handle(this, new Handler(p, onFulfilled, onRejected));
171 | return p;
172 | }
173 | }, {
174 | key: 'catch',
175 | value: function _catch(onRejected) {
176 | return this.then(null, onRejected);
177 | }
178 | }, {
179 | key: 'finally',
180 | value: function _finally(fun) {
181 | return this.then(function (value) {
182 | return Promise.resolve(fun()).then(function () {
183 | return value;
184 | });
185 | }, function (reason) {
186 | return Promise.resolve(fun()).then(function () {
187 | throw reason;
188 | });
189 | });
190 | }
191 | }, {
192 | key: 'getValue',
193 | value: function getValue() {
194 | if (this._state === 3) {
195 | return this._value.getValue();
196 | }
197 | return this._value;
198 | }
199 | }, {
200 | key: 'toString',
201 | value: function toString() {
202 | return '[object Promise]';
203 | }
204 | }]);
205 | return Promise;
206 | }();
207 |
208 | Promise$1._noop = noop;
209 | function doResolve(fun, promise) {
210 | var done = false;
211 | function _resolve(value) {
212 | if (done) return;
213 | done = true;
214 | resolve(promise, value);
215 | }
216 | function _reject(reason) {
217 | if (done) return;
218 | done = true;
219 | reject(promise, reason);
220 | }
221 | try {
222 | fun(_resolve, _reject);
223 | } catch (error) {
224 | _reject(error);
225 | }
226 | }
227 | function resolve(promise, newValue) {
228 | if (promise === newValue) {
229 | reject(promise, new TypeError('A promise cannot be resolved with itself'));
230 | return;
231 | }
232 | if (newValue && ((typeof newValue === 'undefined' ? 'undefined' : _typeof(newValue)) === 'object' || typeof newValue === 'function')) {
233 | var _getThen = getThen(newValue),
234 | _getThen2 = slicedToArray(_getThen, 2),
235 | isError = _getThen2[0],
236 | then = _getThen2[1];
237 |
238 | if (isError) {
239 | reject(promise, then);
240 | return;
241 | }
242 | if (then === promise.then && newValue instanceof Promise$1) {
243 | promise._state = 3;
244 | promise._value = newValue;
245 | finale(promise);
246 | return;
247 | } else if (typeof then === 'function') {
248 | doResolve(then.bind(newValue), promise);
249 | return;
250 | }
251 | }
252 | promise._state = 1;
253 | promise._value = newValue;
254 | finale(promise);
255 | }
256 | function reject(promise, reason) {
257 | promise._state = 2;
258 | promise._value = reason;
259 | finale(promise);
260 | }
261 | function finale(promise) {
262 | if (promise._deferreds) {
263 | if (promise._deferreds.length === 1) {
264 | handle(promise, promise._deferreds[0]);
265 | promise._deferreds = null;
266 | return;
267 | }
268 | var _iteratorNormalCompletion = true;
269 | var _didIteratorError = false;
270 | var _iteratorError = undefined;
271 |
272 | try {
273 | for (var _iterator = promise._deferreds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
274 | var deferred = _step.value;
275 |
276 | handle(promise, deferred);
277 | }
278 | } catch (err) {
279 | _didIteratorError = true;
280 | _iteratorError = err;
281 | } finally {
282 | try {
283 | if (!_iteratorNormalCompletion && _iterator.return) {
284 | _iterator.return();
285 | }
286 | } finally {
287 | if (_didIteratorError) {
288 | throw _iteratorError;
289 | }
290 | }
291 | }
292 |
293 | promise._deferreds = null;
294 | }
295 | }
296 | function handle(promise, deferred) {
297 | while (promise._state === 3) {
298 | promise = promise._value;
299 | }
300 | if (promise._state === 0) {
301 | promise._deferreds ? promise._deferreds.push(deferred) : promise._deferreds = [deferred];
302 | return;
303 | }
304 | handleResolved(promise, deferred);
305 | }
306 | function handleResolved(promise, deferred) {
307 | ascb(function () {
308 | var isResolve = promise._state === 1;
309 | var callback = deferred[isResolve ? 'onFulfilled' : 'onRejected'];
310 | if (callback === null) {
311 | isResolve ? resolve(deferred.promise, promise._value) : reject(deferred.promise, promise._value);
312 | return;
313 | }
314 | try {
315 | var result = callback(promise._value);
316 | resolve(deferred.promise, result);
317 | } catch (error) {
318 | reject(deferred.promise, error);
319 | }
320 | });
321 | }
322 | function getThen(value) {
323 | try {
324 | return [false, value.then];
325 | } catch (error) {
326 | return [true, error];
327 | }
328 | }
329 | function Handler(promise, onFulfilled, onRejected) {
330 | this.promise = promise;
331 | this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
332 | this.onRejected = typeof onRejected === 'function' ? onRejected : null;
333 | }
334 |
335 | Promise$1.resolve = function (value) {
336 | if (value instanceof Promise$1) return value;
337 | function valueToPromise(val) {
338 | var p = new Promise$1(Promise$1._noop);
339 | p._state = 1;
340 | p._value = value;
341 | return p;
342 | }
343 | if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' || typeof value === 'function') {
344 | try {
345 | var then = value.then;
346 | if (typeof then === 'function') {
347 | return new Promise$1(then.bind(value));
348 | }
349 | } catch (error) {
350 | return new Promise$1(function (_, reject) {
351 | reject(error);
352 | });
353 | }
354 | }
355 | return valueToPromise(value);
356 | };
357 | Promise$1.reject = function (reason) {
358 | return new Promise$1(function (_, reject) {
359 | reject(reason);
360 | });
361 | };
362 | Promise$1.all = function (array) {
363 | !Array.isArray(array) && (array = Array.from(array));
364 | return new Promise$1(function (resolve, reject) {
365 | if (array.length === 0) return resolve(array);
366 | var remaining = array.length;
367 | for (var i = 0; i < array.length; i++) {
368 | result(array[i], i);
369 | }
370 | function result(val, i) {
371 | if (!val || (typeof val === 'undefined' ? 'undefined' : _typeof(val)) !== 'object' && typeof val !== 'function') {
372 | array[i] = val;
373 | --remaining === 0 && resolve(array);
374 | return;
375 | }
376 | if (val instanceof Promise$1 && val.then === Promise$1.prototype.then) {
377 | while (val._state === 3) {
378 | val = val._value;
379 | }
380 | if (val._state === 1) return result(val._value, i);
381 | if (val._state === 2) reject(val._value);
382 | val.then(function (res) {
383 | return result(res, i);
384 | }, reject);
385 | return;
386 | }
387 | if (typeof val.then === 'function') {
388 | var p = new Promise$1(val.then.bind(val));
389 | p.then(function (res) {
390 | return result(res, i);
391 | }, reject);
392 | return;
393 | }
394 | }
395 | });
396 | };
397 | Promise$1.race = function (array) {
398 | return new Promise$1(function (resolve, reject) {
399 | var _iteratorNormalCompletion = true;
400 | var _didIteratorError = false;
401 | var _iteratorError = undefined;
402 |
403 | try {
404 | for (var _iterator = array[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
405 | var val = _step.value;
406 |
407 | Promise$1.resolve(val).then(resolve, reject);
408 | }
409 | } catch (err) {
410 | _didIteratorError = true;
411 | _iteratorError = err;
412 | } finally {
413 | try {
414 | if (!_iteratorNormalCompletion && _iterator.return) {
415 | _iterator.return();
416 | }
417 | } finally {
418 | if (_didIteratorError) {
419 | throw _iteratorError;
420 | }
421 | }
422 | }
423 | });
424 | };
425 |
426 | return Promise$1;
427 |
428 | })));
429 |
--------------------------------------------------------------------------------