├── server ├── .jshintrc └── index.js ├── .gitignore ├── test ├── index.js ├── worker.js ├── index.html ├── test-adapter.js └── scheduler-test.js ├── .spmignore ├── auto.js ├── lib ├── es6-promise.js └── es6-promise │ ├── utils.js │ ├── then.js │ ├── polyfill.js │ ├── promise │ ├── resolve.js │ ├── reject.js │ ├── all.js │ └── race.js │ ├── enumerator.js │ ├── asap.js │ ├── -internal.js │ └── promise.js ├── testem.json ├── config ├── versionTemplate.txt └── s3ProjectConfig.js ├── .release.json ├── bower.json ├── .travis.yml ├── bin └── publish_to_s3.js ├── .eslintrc ├── .jshintrc ├── LICENSE ├── vendor └── loader.js ├── package.json ├── CHANGELOG.md ├── README.md ├── Brocfile.js ├── es6-promise.d.ts └── dist ├── es6-promise.min.js ├── es6-promise.auto.min.js ├── es6-promise-polyfill.min.js ├── es6-promise-polyfill.map ├── es6-promise-polyfill.js └── es6-promise.js /server/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true 3 | } 4 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app) { 2 | app.get('/', function(req, res) { 3 | res.redirect('/test/'); 4 | }) 5 | }; 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /promises_tests 3 | /main.js 4 | /tmp 5 | /docs 6 | /dist/test 7 | !/dist/es6-promise.js 8 | !/dist/es6-promise.min.js -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | require('./test-adapter.js'); 2 | require('./scheduler-test.js'); 3 | require('./extension-test.js'); 4 | require('promises-aplus-tests-phantom/lib/testFiles'); 5 | -------------------------------------------------------------------------------- /.spmignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /tmp 3 | /tasks 4 | /test 5 | /vendor 6 | /.jshintrc 7 | /.npmignore 8 | /.travis.yml 9 | /Gruntfile.js 10 | /component.json 11 | /index.html 12 | -------------------------------------------------------------------------------- /auto.js: -------------------------------------------------------------------------------- 1 | // This file can be required in Browserify and Node.js for automatic polyfill 2 | // To use it: require('es6-promise/auto'); 3 | 'use strict'; 4 | module.exports = require('./').polyfill(); 5 | -------------------------------------------------------------------------------- /lib/es6-promise.js: -------------------------------------------------------------------------------- 1 | import Promise from './es6-promise/promise'; 2 | import polyfill from './es6-promise/polyfill'; 3 | 4 | // Strange compat.. 5 | Promise.polyfill = polyfill; 6 | Promise.Promise = Promise; 7 | export default Promise; 8 | -------------------------------------------------------------------------------- /testem.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_page": "test/index.html", 3 | "parallel": 5, 4 | "frameworks": "mocha", 5 | "launchers": { 6 | "Mocha": { 7 | "command": "./node_modules/.bin/mocha dist/test/browserify.js" 8 | } 9 | }, 10 | "launch_in_ci": [ 11 | "PhantomJS", 12 | "Mocha" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /test/worker.js: -------------------------------------------------------------------------------- 1 | importScripts('es6-promise.js'); 2 | new ES6Promise.Promise(function(resolve, reject) { 3 | self.onmessage = function (e) { 4 | if (e.data === 'ping') { 5 | resolve('pong'); 6 | } else { 7 | reject(new Error('wrong message')); 8 | } 9 | }; 10 | }).then(function (result) { 11 | self.postMessage(result); 12 | }, function (err){ 13 | setTimeout(function () { 14 | throw err; 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /config/versionTemplate.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | * @overview es6-promise - a tiny implementation of Promises/A+ (fork by Dropbox). 3 | * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) 4 | * @license Licensed under MIT license 5 | * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE 6 | * @repo https://github.com/dropbox/es6-promise 7 | * @version VERSION_PLACEHOLDER_STRING 8 | */ 9 | -------------------------------------------------------------------------------- /.release.json: -------------------------------------------------------------------------------- 1 | { 2 | "non-interactive": true, 3 | "dry-run": false, 4 | "verbose": false, 5 | "force": false, 6 | "pkgFiles": ["package.json", "bower.json"], 7 | "increment": "patch", 8 | "commitMessage": "Release %s", 9 | "tagName": "v%s", 10 | "tagAnnotation": "Release %s", 11 | "buildCommand": "npm run-script build:production", 12 | "dist": { 13 | "repo": "git@github.com:components/es6-promise.git", 14 | "stageDir": "tmp/stage", 15 | "base": "dist", 16 | "files": ["**/*", "../package.json", "../bower.json"] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/es6-promise/utils.js: -------------------------------------------------------------------------------- 1 | export function objectOrFunction(x) { 2 | return typeof x === 'function' || (typeof x === 'object' && x !== null); 3 | } 4 | 5 | export function isFunction(x) { 6 | return typeof x === 'function'; 7 | } 8 | 9 | export function isMaybeThenable(x) { 10 | return typeof x === 'object' && x !== null; 11 | } 12 | 13 | let _isArray; 14 | if (!Array.isArray) { 15 | _isArray = x => Object.prototype.toString.call(x) === '[object Array]'; 16 | } else { 17 | _isArray = Array.isArray; 18 | } 19 | 20 | export const isArray = _isArray; 21 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rsvp.js Tests 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 19 | 20 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /test/test-adapter.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var Promise = require('./es6-promise'); 3 | 4 | assert(typeof Promise.polyfill === 'function') 5 | assert(typeof Promise.Promise === 'function') 6 | assert(Promise.Promise === Promise) 7 | 8 | function defer() { 9 | var deferred = {}; 10 | 11 | deferred.promise = new Promise(function(resolve, reject) { 12 | deferred.resolve = resolve; 13 | deferred.reject = reject; 14 | }); 15 | 16 | return deferred; 17 | } 18 | 19 | new Function('return this;')().adapter = { 20 | resolved: function(a) { return Promise.resolve(a); }, 21 | rejected: function(a) { return Promise.reject(a); }, 22 | deferred: defer, 23 | Promise: Promise 24 | }; 25 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "es6-promise", 3 | "namespace": "Promise", 4 | "version": "4.0.5", 5 | "description": "A polyfill for ES6-style Promises, tracking rsvp", 6 | "authors": [ 7 | "Stefan Penner " 8 | ], 9 | "main": "dist/es6-promise.js", 10 | "keywords": [ 11 | "promise" 12 | ], 13 | "repository": { 14 | "type": "git", 15 | "url": "git://github.com/stefanpenner/es6-promise.git" 16 | }, 17 | "bugs": { 18 | "url": "https://github.com/stefanpenner/es6-promise/issues" 19 | }, 20 | "license": "MIT", 21 | "ignore": [ 22 | "node_modules", 23 | "bower_components", 24 | "test", 25 | "tests", 26 | "vendor", 27 | "tasks" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /config/s3ProjectConfig.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Using wildcard because es6-promise does not currently have a 3 | * channel system in place. 4 | */ 5 | module.exports = function(revision,tag,date){ 6 | return { 7 | 'es6-promise.js': 8 | { contentType: 'text/javascript', 9 | destinations: { 10 | wildcard: [ 11 | 'es6-promise-latest.js', 12 | 'es6-promise-' + revision + '.js' 13 | ] 14 | } 15 | }, 16 | 'es6-promise.min.js': 17 | { contentType: 'text/javascript', 18 | destinations: { 19 | wildcard: [ 20 | 'es6-promise-latest.min.js', 21 | 'es6-promise-' + revision + '.min.js' 22 | ] 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/es6-promise/then.js: -------------------------------------------------------------------------------- 1 | import { 2 | invokeCallback, 3 | subscribe, 4 | FULFILLED, 5 | REJECTED, 6 | noop, 7 | makePromise, 8 | PROMISE_ID 9 | } from './-internal'; 10 | 11 | import { asap } from './asap'; 12 | 13 | export default function then(onFulfillment, onRejection) { 14 | const parent = this; 15 | 16 | parent._onerror = null; 17 | 18 | const child = new this.constructor(noop); 19 | 20 | if (child[PROMISE_ID] === undefined) { 21 | makePromise(child); 22 | } 23 | 24 | const { _state } = parent; 25 | 26 | if (_state) { 27 | const callback = arguments[_state - 1]; 28 | asap(() => invokeCallback(_state, child, callback, parent._result)); 29 | } else { 30 | subscribe(parent, child, onFulfillment, onRejection); 31 | } 32 | 33 | return child; 34 | } 35 | -------------------------------------------------------------------------------- /lib/es6-promise/polyfill.js: -------------------------------------------------------------------------------- 1 | /*global self*/ 2 | import Promise from './promise'; 3 | 4 | export default function polyfill() { 5 | let local; 6 | 7 | if (typeof global !== 'undefined') { 8 | local = global; 9 | } else if (typeof self !== 'undefined') { 10 | local = self; 11 | } else { 12 | try { 13 | local = Function('return this')(); 14 | } catch (e) { 15 | throw new Error('polyfill failed because global object is unavailable in this environment'); 16 | } 17 | } 18 | 19 | let P = local.Promise; 20 | 21 | if (P) { 22 | var promiseToString = null; 23 | try { 24 | promiseToString = Object.prototype.toString.call(P.resolve()); 25 | } catch(e) { 26 | // silently ignored 27 | } 28 | 29 | if (promiseToString === '[object Promise]' && !P.cast){ 30 | return; 31 | } 32 | } 33 | 34 | local.Promise = Promise; 35 | } 36 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6" 4 | - "5" 5 | - "4" 6 | - "0.12" 7 | after_success: 8 | - "./bin/publish_to_s3.js" 9 | before_install: 10 | - nvm install 6 11 | - nvm use 6 12 | - export PATH=/usr/local/phantomjs-2.0.0/bin:$PATH 13 | before_script: 14 | - nvm use $TRAVIS_NODE_VERSION 15 | env: 16 | global: 17 | - EMBER_ENV=production 18 | - secure: MiR5zbpHpblG1HcQyxzhYqxcb+3gGsjKWOjLYi1AOU4BG90+Ckim4mCJbneIHaBfeIZKZCm+X1wRRwUE0TlaMFEiXqReHt8k/1ChjfFdTicZtXYytbnGdRlHjvN/LVCaVhBiORSXWPzjIWhwYInMhCtekWTOqChtblRGdbrCLCY= 19 | - secure: LF1yJIzr4z5e4RxFt+ZIwjazDyItPoPtSUgcoSQfTUhRtkxFsIRpOpf4VnzPH2FSpw4wbkNq+hm+K1xrKHNq+OE0PLYtD+H7i03ac993jReSJN8rwb0gpAlwAGWC++uF7j7aMKJAlZA1u4tnPD5cxuk6BKnNSONtD0BwKQ6oXkk= 20 | - secure: MB2RZPsHVuikayckVYCVE9TWiooaFV+jyxEkpSoNJ5pRIVTwy9xRHK56S1sxkXmPIm7sYyaLWpngp13/CN80pT796HS8mEuxJ011XwjY6YutXHnR2gOrCssah6kQ6gaXO1sFVkerBa/GwdkKu/k8LVAiORiz1JlPZvOKDRsJaNw= 21 | -------------------------------------------------------------------------------- /bin/publish_to_s3.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // To invoke this from the commandline you need the following to env vars to exist: 4 | // 5 | // S3_BUCKET_NAME 6 | // TRAVIS_BRANCH 7 | // TRAVIS_TAG 8 | // TRAVIS_COMMIT 9 | // S3_SECRET_ACCESS_KEY 10 | // S3_ACCESS_KEY_ID 11 | // 12 | // Once you have those you execute with the following: 13 | // 14 | // ```sh 15 | // ./bin/publish_to_s3.js 16 | // ``` 17 | var S3Publisher = require('ember-publisher'); 18 | var configPath = require('path').join(__dirname, '../config/s3ProjectConfig.js'); 19 | publisher = new S3Publisher({ projectConfigPath: configPath }); 20 | 21 | // Always use wildcard section of project config. 22 | // This is useful when the including library does not 23 | // require channels (like in ember.js / ember-data). 24 | publisher.currentBranch = function() { 25 | return (process.env.TRAVIS_BRANCH === 'master') ? 'wildcard' : 'no-op'; 26 | }; 27 | publisher.publish(); 28 | 29 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "ember", 3 | 4 | "parser": "babel-eslint", 5 | 6 | "ecmaFeatures": { 7 | modules: true, 8 | blockBindings: true, 9 | arrowFunctions: true, 10 | objectLiteralShorthandMethods: true, 11 | objectLiteralShorthandProperties: true, 12 | templateStrings: true 13 | }, 14 | 15 | "rules": { 16 | "indent": [ 2, "tab", { "SwitchCase": 1 } ], 17 | "object-shorthand": [ 2, "always" ], 18 | "prefer-const": 0, 19 | "comma-dangle": 0, 20 | "spaced-comment": 1, 21 | "object-curly-spacing": [2, "always"], 22 | "arrow-spacing": [ 1, { before: true, after: true } ], 23 | "array-bracket-spacing": [ 2, "always" ], 24 | "no-restricted-syntax": 0, 25 | "no-warning-comments": [ 0, { "terms": [ "todo", "fixme", "xxx" ], "location": "start" } ], 26 | "no-ternary": 0, 27 | "no-nested-ternary": 2, 28 | "brace-style": [ 2, "stroustrup" ], 29 | "no-else-return": 0 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "console", 4 | "require", 5 | "equal", 6 | "test", 7 | "testBoth", 8 | "testWithDefault", 9 | "raises", 10 | "deepEqual", 11 | "start", 12 | "stop", 13 | "ok", 14 | "strictEqual", 15 | "module", 16 | "expect" 17 | ], 18 | 19 | "esnext": true, 20 | "proto": true, 21 | "node" : true, 22 | "browser" : true, 23 | 24 | "boss" : true, 25 | "curly": false, 26 | "debug": false, 27 | "devel": false, 28 | "eqeqeq": true, 29 | "evil": true, 30 | "forin": false, 31 | "immed": false, 32 | "laxbreak": false, 33 | "newcap": true, 34 | "noarg": true, 35 | "noempty": false, 36 | "nonew": false, 37 | "nomen": false, 38 | "onevar": false, 39 | "plusplus": false, 40 | "regexp": false, 41 | "undef": true, 42 | "sub": true, 43 | "strict": false, 44 | "white": false, 45 | "eqnull": true 46 | } 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /lib/es6-promise/promise/resolve.js: -------------------------------------------------------------------------------- 1 | import { 2 | noop, 3 | resolve as _resolve 4 | } from '../-internal'; 5 | 6 | /** 7 | `Promise.resolve` returns a promise that will become resolved with the 8 | passed `value`. It is shorthand for the following: 9 | 10 | ```javascript 11 | let promise = new Promise(function(resolve, reject){ 12 | resolve(1); 13 | }); 14 | 15 | promise.then(function(value){ 16 | // value === 1 17 | }); 18 | ``` 19 | 20 | Instead of writing the above, your code now simply becomes the following: 21 | 22 | ```javascript 23 | let promise = Promise.resolve(1); 24 | 25 | promise.then(function(value){ 26 | // value === 1 27 | }); 28 | ``` 29 | 30 | @method resolve 31 | @static 32 | @param {Any} value value that the returned promise will be resolved with 33 | Useful for tooling. 34 | @return {Promise} a promise that will become fulfilled with the given 35 | `value` 36 | */ 37 | export default function resolve(object) { 38 | /*jshint validthis:true */ 39 | let Constructor = this; 40 | 41 | if (object && typeof object === 'object' && object.constructor === Constructor) { 42 | return object; 43 | } 44 | 45 | let promise = new Constructor(noop); 46 | _resolve(promise, object); 47 | return promise; 48 | } 49 | -------------------------------------------------------------------------------- /lib/es6-promise/promise/reject.js: -------------------------------------------------------------------------------- 1 | import { 2 | noop, 3 | reject as _reject 4 | } from '../-internal'; 5 | 6 | /** 7 | `Promise.reject` returns a promise rejected with the passed `reason`. 8 | It is shorthand for the following: 9 | 10 | ```javascript 11 | let promise = new Promise(function(resolve, reject){ 12 | reject(new Error('WHOOPS')); 13 | }); 14 | 15 | promise.then(function(value){ 16 | // Code here doesn't run because the promise is rejected! 17 | }, function(reason){ 18 | // reason.message === 'WHOOPS' 19 | }); 20 | ``` 21 | 22 | Instead of writing the above, your code now simply becomes the following: 23 | 24 | ```javascript 25 | let promise = Promise.reject(new Error('WHOOPS')); 26 | 27 | promise.then(function(value){ 28 | // Code here doesn't run because the promise is rejected! 29 | }, function(reason){ 30 | // reason.message === 'WHOOPS' 31 | }); 32 | ``` 33 | 34 | @method reject 35 | @static 36 | @param {Any} reason value that the returned promise will be rejected with. 37 | Useful for tooling. 38 | @return {Promise} a promise rejected with the given `reason`. 39 | */ 40 | export default function reject(reason) { 41 | /*jshint validthis:true */ 42 | let Constructor = this; 43 | let promise = new Constructor(noop); 44 | _reject(promise, reason); 45 | return promise; 46 | } 47 | -------------------------------------------------------------------------------- /vendor/loader.js: -------------------------------------------------------------------------------- 1 | var define, requireModule, require, requirejs; 2 | 3 | (function() { 4 | var registry = {}, seen = {}; 5 | 6 | define = function(name, deps, callback) { 7 | registry[name] = { deps: deps, callback: callback }; 8 | }; 9 | 10 | requirejs = require = requireModule = function(name) { 11 | requirejs._eak_seen = registry; 12 | 13 | if (seen[name]) { return seen[name]; } 14 | seen[name] = {}; 15 | 16 | if (!registry[name]) { 17 | throw new Error("Could not find module " + name); 18 | } 19 | 20 | var mod = registry[name], 21 | deps = mod.deps, 22 | callback = mod.callback, 23 | reified = [], 24 | exports; 25 | 26 | for (var i=0, l=deps.length; i 2 and the overriden scheduling mechanism would not 17 | // be used. 18 | // This is required because the test library uses Promise. 19 | setTimeout(function() { 20 | var microtasks = []; 21 | var resolvedWith = null; 22 | 23 | Promise._setScheduler(function(fn) { 24 | microtasks.push(fn); 25 | }); 26 | 27 | Promise.resolve('value').then(function(v) { 28 | resolvedWith = v; 29 | }); 30 | 31 | assert.equal(resolvedWith, null); 32 | assert.equal(microtasks.length, 1); 33 | 34 | while (microtasks.length) { 35 | microtasks.shift()(); 36 | } 37 | 38 | assert.equal(resolvedWith, 'value'); 39 | 40 | // restore the original scheduler 41 | Promise._setScheduler(void 0); 42 | done(); 43 | }); 44 | }); 45 | }); 46 | 47 | describe('Promise._asap', function() { 48 | it('should allow enqueuing microtasks', function(done) { 49 | Promise._asap(function(arg) { 50 | assert.equal(arg, 'arg'); 51 | done(); 52 | }, 'arg'); 53 | }); 54 | }); 55 | 56 | describe('Promise._setAsap', function() { 57 | it('should allow overriding asap', function(done) { 58 | var called = false; 59 | 60 | Promise._setAsap(function(fn, arg) { 61 | called = true; 62 | // call the original implementation 63 | Promise._asap(fn, arg); 64 | // restore the original implementation 65 | Promise._setAsap(Promise._asap); 66 | }); 67 | 68 | Promise.resolve('value').then(function(v) { 69 | resolvedWith = v; 70 | assert.equal(v, 'value'); 71 | assert.equal(called, true); 72 | done(); 73 | }); 74 | }); 75 | }); 76 | }); 77 | -------------------------------------------------------------------------------- /lib/es6-promise/promise/race.js: -------------------------------------------------------------------------------- 1 | import { 2 | isArray 3 | } from "../utils"; 4 | 5 | /** 6 | `Promise.race` returns a new promise which is settled in the same way as the 7 | first passed promise to settle. 8 | 9 | Example: 10 | 11 | ```javascript 12 | let promise1 = new Promise(function(resolve, reject){ 13 | setTimeout(function(){ 14 | resolve('promise 1'); 15 | }, 200); 16 | }); 17 | 18 | let promise2 = new Promise(function(resolve, reject){ 19 | setTimeout(function(){ 20 | resolve('promise 2'); 21 | }, 100); 22 | }); 23 | 24 | Promise.race([promise1, promise2]).then(function(result){ 25 | // result === 'promise 2' because it was resolved before promise1 26 | // was resolved. 27 | }); 28 | ``` 29 | 30 | `Promise.race` is deterministic in that only the state of the first 31 | settled promise matters. For example, even if other promises given to the 32 | `promises` array argument are resolved, but the first settled promise has 33 | become rejected before the other promises became fulfilled, the returned 34 | promise will become rejected: 35 | 36 | ```javascript 37 | let promise1 = new Promise(function(resolve, reject){ 38 | setTimeout(function(){ 39 | resolve('promise 1'); 40 | }, 200); 41 | }); 42 | 43 | let promise2 = new Promise(function(resolve, reject){ 44 | setTimeout(function(){ 45 | reject(new Error('promise 2')); 46 | }, 100); 47 | }); 48 | 49 | Promise.race([promise1, promise2]).then(function(result){ 50 | // Code here never runs 51 | }, function(reason){ 52 | // reason.message === 'promise 2' because promise 2 became rejected before 53 | // promise 1 became fulfilled 54 | }); 55 | ``` 56 | 57 | An example real-world use case is implementing timeouts: 58 | 59 | ```javascript 60 | Promise.race([ajax('foo.json'), timeout(5000)]) 61 | ``` 62 | 63 | @method race 64 | @static 65 | @param {Array} promises array of promises to observe 66 | Useful for tooling. 67 | @return {Promise} a promise which settles in the same way as the first passed 68 | promise to settle. 69 | */ 70 | export default function race(entries) { 71 | /*jshint validthis:true */ 72 | let Constructor = this; 73 | 74 | if (!isArray(entries)) { 75 | return new Constructor((_, reject) => reject(new TypeError('You must pass an array to race.'))); 76 | } else { 77 | return new Constructor((resolve, reject) => { 78 | let length = entries.length; 79 | for (let i = 0; i < length; i++) { 80 | Constructor.resolve(entries[i]).then(resolve, reject); 81 | } 82 | }); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/es6-promise/enumerator.js: -------------------------------------------------------------------------------- 1 | import { 2 | isArray, 3 | isMaybeThenable 4 | } from './utils'; 5 | 6 | import { 7 | noop, 8 | reject, 9 | fulfill, 10 | subscribe, 11 | FULFILLED, 12 | REJECTED, 13 | PENDING, 14 | getThen, 15 | handleMaybeThenable 16 | } from './-internal'; 17 | 18 | import then from './then'; 19 | import Promise from './promise'; 20 | import originalResolve from './promise/resolve'; 21 | import originalThen from './then'; 22 | import { makePromise, PROMISE_ID } from './-internal'; 23 | 24 | export default Enumerator; 25 | function Enumerator(Constructor, input) { 26 | this._instanceConstructor = Constructor; 27 | this.promise = new Constructor(noop); 28 | 29 | if (!this.promise[PROMISE_ID]) { 30 | makePromise(this.promise); 31 | } 32 | 33 | if (isArray(input)) { 34 | this._input = input; 35 | this.length = input.length; 36 | this._remaining = input.length; 37 | 38 | this._result = new Array(this.length); 39 | 40 | if (this.length === 0) { 41 | fulfill(this.promise, this._result); 42 | } else { 43 | this.length = this.length || 0; 44 | this._enumerate(); 45 | if (this._remaining === 0) { 46 | fulfill(this.promise, this._result); 47 | } 48 | } 49 | } else { 50 | reject(this.promise, validationError()); 51 | } 52 | } 53 | 54 | function validationError() { 55 | return new Error('Array Methods must be provided an Array'); 56 | }; 57 | 58 | Enumerator.prototype._enumerate = function() { 59 | let { length, _input } = this; 60 | 61 | for (let i = 0; this._state === PENDING && i < length; i++) { 62 | this._eachEntry(_input[i], i); 63 | } 64 | }; 65 | 66 | Enumerator.prototype._eachEntry = function(entry, i) { 67 | let c = this._instanceConstructor; 68 | let { resolve } = c; 69 | 70 | if (resolve === originalResolve) { 71 | let then = getThen(entry); 72 | 73 | if (then === originalThen && 74 | entry._state !== PENDING) { 75 | entry._onerror = null; 76 | this._settledAt(entry._state, i, entry._result); 77 | } else if (typeof then !== 'function') { 78 | this._remaining--; 79 | this._result[i] = entry; 80 | } else if (c === Promise) { 81 | let promise = new c(noop); 82 | handleMaybeThenable(promise, entry, then); 83 | this._willSettleAt(promise, i); 84 | } else { 85 | this._willSettleAt(new c(resolve => resolve(entry)), i); 86 | } 87 | } else { 88 | this._willSettleAt(resolve(entry), i); 89 | } 90 | }; 91 | 92 | Enumerator.prototype._settledAt = function(state, i, value) { 93 | let { promise } = this; 94 | 95 | if (promise._state === PENDING) { 96 | this._remaining--; 97 | 98 | if (state === REJECTED) { 99 | reject(promise, value); 100 | } else { 101 | this._result[i] = value; 102 | } 103 | } 104 | 105 | if (this._remaining === 0) { 106 | fulfill(promise, this._result); 107 | } 108 | }; 109 | 110 | Enumerator.prototype._willSettleAt = function(promise, i) { 111 | let enumerator = this; 112 | 113 | subscribe(promise, undefined, value => enumerator._settledAt(FULFILLED, i, value), 114 | reason => enumerator._settledAt(REJECTED, i, reason)); 115 | }; 116 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Master 2 | 3 | # 4.0.5 4 | 5 | * fix require('es6-promise/auto') for Node < 4 6 | 7 | # 4.0.4 8 | 9 | * fix asap when using https://github.com/Kinvey/titanium-sdk 10 | 11 | # 4.0.3 12 | 13 | * fix Readme links 14 | 15 | # 4.0.2 16 | 17 | * fix require('es6-promise/auto'); 18 | 19 | # 4.0.0 20 | 21 | * no longer polyfill automatically, if needed one can still invoke 22 | `require('es6-promise/auto')` directly. 23 | 24 | # 3.3.1 25 | 26 | * fix links in readme 27 | 28 | # 3.3.0 29 | 30 | * support polyfil on WebMAF (playstation env) 31 | * fix tampering related bug global `constructor` was referenced by mistake. 32 | * provide TS Typings 33 | * increase compatibliity with sinon.useFakeTimers(); 34 | * update build tools (use rollup) 35 | * directly export promise; 36 | 37 | # 3.2.2 38 | 39 | * IE8: use isArray 40 | * update build dependencies 41 | 42 | # 3.2.1 43 | 44 | * fix race tampering issue 45 | * use eslint 46 | * fix Promise.all tampering 47 | * remove unused code 48 | * fix issues with NWJS/electron 49 | 50 | # 3.2.0 51 | 52 | * improve tamper resistence of Promise.all Promise.race and 53 | Promise.prototype.then (note, this isn't complete, but addresses an exception 54 | when used \w core-js, follow up work will address entirely) 55 | * remove spec incompatible then chaining fast-path 56 | * add eslint 57 | * update build deps 58 | 59 | # 3.1.2 60 | 61 | * fix node detection issues with NWJS/electron 62 | 63 | # 3.1.0 64 | 65 | * improve performance of Promise.all when it encounters a non-promise input object input 66 | * then/resolve tamper protection 67 | * reduce AST size of promise constructor, to facilitate more inlining 68 | * Update README.md with details about PhantomJS requirement for running tests 69 | * Mangle and compress the minified version 70 | 71 | # 3.0.2 72 | 73 | * correctly bump both bower and package.json versions 74 | 75 | # 3.0.1 76 | 77 | * no longer include dist/test in npm releases 78 | 79 | # 3.0.0 80 | 81 | * use nextTick() instead of setImmediate() to schedule microtasks with node 0.10. Later versions of 82 | nodes are not affected as they were already using nextTick(). Note that using nextTick() might 83 | trigger a depreciation warning on 0.10 as described at https://github.com/cujojs/when/issues/410. 84 | The reason why nextTick() is preferred is that is setImmediate() would schedule a macrotask 85 | instead of a microtask and might result in a different scheduling. 86 | If needed you can revert to the former behavior as follow: 87 | 88 | var Promise = require('es6-promise').Promise; 89 | Promise._setScheduler(setImmediate); 90 | 91 | # 2.3.0 92 | 93 | * #121: Ability to override the internal asap implementation 94 | * #120: Use an ascii character for an apostrophe, for source maps 95 | 96 | # 2.2.0 97 | 98 | * #116: Expose asap() and a way to override the scheduling mechanism on Promise 99 | * Lock to v0.2.3 of ember-cli 100 | 101 | # 2.1.1 102 | 103 | * Fix #100 via #105: tell browserify to ignore vertx require 104 | * Fix #101 via #102: "follow thenable state, not own state" 105 | 106 | # 2.1.0 107 | 108 | * #59: Automatic polyfill. No need to invoke `ES6Promise.polyfill()` anymore. 109 | * ... (see the commit log) 110 | 111 | # 2.0.0 112 | 113 | * re-sync with RSVP. Many large performance improvements and bugfixes. 114 | 115 | # 1.0.0 116 | 117 | * first subset of RSVP 118 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # THIS IS A FORK 2 | 3 | The forked version allows specifying unhandled rejection handler via `Promise.onerror`: 4 | 5 | ```javascript 6 | Promise.onerror = function(reason) { 7 | // You can do error reporting here. 8 | // Simply log for demo purpose. 9 | console.log(error); 10 | } 11 | 12 | // Console should log 42 asynchronously. 13 | Promise.reject(42); 14 | ``` 15 | 16 | # ES6-Promise (subset of [rsvp.js](https://github.com/tildeio/rsvp.js)) [![Build Status](https://travis-ci.org/stefanpenner/es6-promise.svg?branch=master)](https://travis-ci.org/stefanpenner/es6-promise) 17 | 18 | This is a polyfill of the [ES6 Promise](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-constructor). The implementation is a subset of [rsvp.js](https://github.com/tildeio/rsvp.js) extracted by @jakearchibald, if you're wanting extra features and more debugging options, check out the [full library](https://github.com/tildeio/rsvp.js). 19 | 20 | For API details and how to use promises, see the JavaScript Promises HTML5Rocks article. 21 | 22 | ## Downloads 23 | 24 | * [es6-promise 27.86 KB (7.33 KB gzipped)](https://raw.githubusercontent.com/stefanpenner/es6-promise/master/dist/es6-promise.js) 25 | * [es6-promise-auto 27.78 KB (7.3 KB gzipped)](https://raw.githubusercontent.com/stefanpenner/es6-promise/master/dist/es6-promise.auto.js) - Automatically provides/replaces `Promise` if missing or broken. 26 | * [es6-promise-min 6.17 KB (2.4 KB gzipped)](https://raw.githubusercontent.com/stefanpenner/es6-promise/master/dist/es6-promise.min.js) 27 | * [es6-promise-auto-min 6.19 KB (2.4 KB gzipped)](https://raw.githubusercontent.com/stefanpenner/es6-promise/master/dist/es6-promise.auto.min.js) - Minified version of `es6-promise-auto` above. 28 | 29 | ## Node.js 30 | 31 | To install: 32 | 33 | ```sh 34 | npm install es6-promise 35 | ``` 36 | 37 | To use: 38 | 39 | ```js 40 | var Promise = require('es6-promise').Promise; 41 | ``` 42 | 43 | ## Bower 44 | 45 | To install: 46 | 47 | ```sh 48 | bower install es6-promise --save 49 | ``` 50 | 51 | 52 | ## Usage in IE<9 53 | 54 | `catch` is a reserved word in IE<9, meaning `promise.catch(func)` throws a syntax error. To work around this, you can use a string to access the property as shown in the following example. 55 | 56 | However, please remember that such technique is already provided by most common minifiers, making the resulting code safe for old browsers and production: 57 | 58 | ```js 59 | promise['catch'](function(err) { 60 | // ... 61 | }); 62 | ``` 63 | 64 | Or use `.then` instead: 65 | 66 | ```js 67 | promise.then(undefined, function(err) { 68 | // ... 69 | }); 70 | ``` 71 | 72 | ## Auto-polyfill 73 | 74 | To polyfill the global environment (either in Node or in the browser via CommonJS) use the following code snippet: 75 | 76 | ```js 77 | require('es6-promise').polyfill(); 78 | ``` 79 | 80 | Alternatively 81 | 82 | ```js 83 | require('es6-promise/auto'); 84 | ``` 85 | 86 | Notice that we don't assign the result of `polyfill()` to any variable. The `polyfill()` method will patch the global environment (in this case to the `Promise` name) when called. 87 | 88 | ## Building & Testing 89 | 90 | You will need to have PhantomJS installed globally in order to run the tests. 91 | 92 | `npm install -g phantomjs` 93 | 94 | * `npm run build` to build 95 | * `npm test` to run tests 96 | * `npm start` to run a build watcher, and webserver to test 97 | * `npm run test:server` for a testem test runner and watching builder 98 | -------------------------------------------------------------------------------- /lib/es6-promise/asap.js: -------------------------------------------------------------------------------- 1 | let len = 0; 2 | let vertxNext; 3 | let customSchedulerFn; 4 | 5 | export var asap = function asap(callback, arg) { 6 | queue[len] = callback; 7 | queue[len + 1] = arg; 8 | len += 2; 9 | if (len === 2) { 10 | // If len is 2, that means that we need to schedule an async flush. 11 | // If additional callbacks are queued before the queue is flushed, they 12 | // will be processed by this flush that we are scheduling. 13 | if (customSchedulerFn) { 14 | customSchedulerFn(flush); 15 | } else { 16 | scheduleFlush(); 17 | } 18 | } 19 | } 20 | 21 | export function setScheduler(scheduleFn) { 22 | customSchedulerFn = scheduleFn; 23 | } 24 | 25 | export function setAsap(asapFn) { 26 | asap = asapFn; 27 | } 28 | 29 | const browserWindow = (typeof window !== 'undefined') ? window : undefined; 30 | const browserGlobal = browserWindow || {}; 31 | const BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; 32 | const isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]'; 33 | 34 | // test for web worker but not in IE10 35 | const isWorker = typeof Uint8ClampedArray !== 'undefined' && 36 | typeof importScripts !== 'undefined' && 37 | typeof MessageChannel !== 'undefined'; 38 | 39 | // node 40 | function useNextTick() { 41 | // node version 0.10.x displays a deprecation warning when nextTick is used recursively 42 | // see https://github.com/cujojs/when/issues/410 for details 43 | return () => process.nextTick(flush); 44 | } 45 | 46 | // vertx 47 | function useVertxTimer() { 48 | if (typeof vertxNext !== 'undefined') { 49 | return function() { 50 | vertxNext(flush); 51 | }; 52 | } 53 | 54 | return useSetTimeout(); 55 | } 56 | 57 | function useMutationObserver() { 58 | let iterations = 0; 59 | const observer = new BrowserMutationObserver(flush); 60 | const node = document.createTextNode(''); 61 | observer.observe(node, { characterData: true }); 62 | 63 | return () => { 64 | node.data = (iterations = ++iterations % 2); 65 | }; 66 | } 67 | 68 | // web worker 69 | function useMessageChannel() { 70 | const channel = new MessageChannel(); 71 | channel.port1.onmessage = flush; 72 | return () => channel.port2.postMessage(0); 73 | } 74 | 75 | function useSetTimeout() { 76 | // Store setTimeout reference so es6-promise will be unaffected by 77 | // other code modifying setTimeout (like sinon.useFakeTimers()) 78 | const globalSetTimeout = setTimeout; 79 | return () => globalSetTimeout(flush, 1); 80 | } 81 | 82 | const queue = new Array(1000); 83 | function flush() { 84 | for (let i = 0; i < len; i+=2) { 85 | let callback = queue[i]; 86 | let arg = queue[i+1]; 87 | 88 | callback(arg); 89 | 90 | queue[i] = undefined; 91 | queue[i+1] = undefined; 92 | } 93 | 94 | len = 0; 95 | } 96 | 97 | function attemptVertx() { 98 | try { 99 | const r = require; 100 | const vertx = r('vertx'); 101 | vertxNext = vertx.runOnLoop || vertx.runOnContext; 102 | return useVertxTimer(); 103 | } catch(e) { 104 | return useSetTimeout(); 105 | } 106 | } 107 | 108 | let scheduleFlush; 109 | // Decide what async method to use to triggering processing of queued callbacks: 110 | if (isNode) { 111 | scheduleFlush = useNextTick(); 112 | } else if (BrowserMutationObserver) { 113 | scheduleFlush = useMutationObserver(); 114 | } else if (isWorker) { 115 | scheduleFlush = useMessageChannel(); 116 | } else if (browserWindow === undefined && typeof require === 'function') { 117 | scheduleFlush = attemptVertx(); 118 | } else { 119 | scheduleFlush = useSetTimeout(); 120 | } 121 | -------------------------------------------------------------------------------- /Brocfile.js: -------------------------------------------------------------------------------- 1 | /* jshint node:true, undef:true, unused:true */ 2 | var Rollup = require('broccoli-rollup'); 3 | var Babel = require('broccoli-babel-transpiler'); 4 | var merge = require('broccoli-merge-trees'); 5 | var uglify = require('broccoli-uglify-js'); 6 | var version = require('git-repo-version'); 7 | var watchify = require('broccoli-watchify'); 8 | var concat = require('broccoli-concat'); 9 | var fs = require('fs'); 10 | 11 | var stew = require('broccoli-stew'); 12 | 13 | var find = stew.find; 14 | var mv = stew.mv; 15 | var rename = stew.rename; 16 | var env = stew.env; 17 | var map = stew.map; 18 | 19 | var lib = find('lib'); 20 | 21 | // test stuff 22 | var testDir = find('test'); 23 | var testFiles = find('test/{index.html,worker.js}'); 24 | 25 | var json3 = mv(find('node_modules/json3/lib/{json3.js}'), 'node_modules/json3/lib/', 'test/'); 26 | // mocha doesn't browserify correctly 27 | var mocha = mv(find('node_modules/mocha/mocha.{js,css}'), 'node_modules/mocha/', 'test/'); 28 | 29 | var testVendor = merge([ json3, mocha ]); 30 | 31 | 32 | var es5 = new Babel(lib, { 33 | blacklist: ['es6.modules'] 34 | }); 35 | 36 | // build RSVP itself 37 | var es6Promise = new Rollup(es5, { 38 | rollup: { 39 | entry: 'lib/es6-promise.js', 40 | targets: [ 41 | { 42 | format: 'umd', 43 | moduleName: 'ES6Promise', 44 | dest: 'es6-promise.js', 45 | sourceMap: 'inline' 46 | } 47 | ] 48 | } 49 | }); 50 | 51 | var testBundle = watchify(merge([ 52 | mv(es6Promise, 'test'), 53 | testDir 54 | ]), { 55 | browserify: { debug: true, entries: ['./test/index.js'] } 56 | }); 57 | 58 | var header = stew.map(find('config/versionTemplate.txt'), function(content) { 59 | return content.replace(/VERSION_PLACEHOLDER_STRING/, version()); 60 | }); 61 | 62 | var dist = es6Promise; 63 | 64 | function concatAs(tree, outputFile) { 65 | return merge([ 66 | concat(merge([tree, header]), { 67 | headerFiles: ['config/versionTemplate.txt'], 68 | inputFiles: ['es6-promise.js'], 69 | outputFile: outputFile 70 | }), 71 | 72 | concat(merge([tree, header]), { 73 | headerFiles: ['config/versionTemplate.txt'], 74 | inputFiles: ['es6-promise.js'], 75 | outputFile: outputFile.replace('es6-promise', 'es6-promise.auto'), 76 | footer: 'ES6Promise.polyfill();', 77 | }), 78 | 79 | ]); 80 | } 81 | 82 | function production(dist, header) { 83 | var result; 84 | env('production', function(){ 85 | result = uglify(concatAs(dist, 'es6-promise.min.js'), { 86 | compress: true, 87 | mangle: true, 88 | }); 89 | }) 90 | return result; 91 | } 92 | 93 | function development(dist, header) { 94 | return concatAs(dist, 'es6-promise.js'); 95 | } 96 | 97 | // Unconditional polyfill build 98 | var polyfillDist = new Rollup(es5, { 99 | rollup: { 100 | entry: 'lib/es6-promise/promise.js', 101 | targets: [ 102 | { 103 | format: 'iife', 104 | moduleName: 'Promise', 105 | dest: 'es6-promise-polyfill.js', 106 | } 107 | ] 108 | } 109 | }); 110 | 111 | var es6PromisePolyfill = function (polyfillDist, header) { 112 | return concat(merge([polyfillDist, header]), { 113 | headerFiles: ['config/versionTemplate.txt'], 114 | inputFiles: ['es6-promise-polyfill.js'], 115 | outputFile: 'es6-promise-polyfill.js' 116 | }); 117 | } 118 | 119 | module.exports = merge([ 120 | merge([ 121 | production(es6Promise, header), 122 | development(es6Promise, header), 123 | ].filter(Boolean)), 124 | // polyfill 125 | es6PromisePolyfill(polyfillDist, header), 126 | // test stuff 127 | testFiles, 128 | testVendor, 129 | mv(testBundle, 'test') 130 | ]); 131 | -------------------------------------------------------------------------------- /es6-promise.d.ts: -------------------------------------------------------------------------------- 1 | export interface Thenable { 2 | then (onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => U | Thenable): Thenable; 3 | then (onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => void): Thenable; 4 | } 5 | 6 | export class Promise implements Thenable { 7 | /** 8 | * If you call resolve in the body of the callback passed to the constructor, 9 | * your promise is fulfilled with result object passed to resolve. 10 | * If you call reject your promise is rejected with the object passed to resolve. 11 | * For consistency and debugging (eg stack traces), obj should be an instanceof Error. 12 | * Any errors thrown in the constructor callback will be implicitly passed to reject(). 13 | */ 14 | constructor (callback: (resolve : (value?: R | Thenable) => void, reject: (error?: any) => void) => void); 15 | 16 | /** 17 | * onFulfilled is called when/if "promise" resolves. onRejected is called when/if "promise" rejects. 18 | * Both are optional, if either/both are omitted the next onFulfilled/onRejected in the chain is called. 19 | * Both callbacks have a single parameter , the fulfillment value or rejection reason. 20 | * "then" returns a new promise equivalent to the value you return from onFulfilled/onRejected after being passed through Promise.resolve. 21 | * If an error is thrown in the callback, the returned promise rejects with that error. 22 | * 23 | * @param onFulfilled called when/if "promise" resolves 24 | * @param onRejected called when/if "promise" rejects 25 | */ 26 | then (onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => U | Thenable): Promise; 27 | then (onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => void): Promise; 28 | 29 | /** 30 | * Sugar for promise.then(undefined, onRejected) 31 | * 32 | * @param onRejected called when/if "promise" rejects 33 | */ 34 | catch (onRejected?: (error: any) => U | Thenable): Promise; 35 | 36 | /** 37 | * onSettled is invoked when/if the "promise" settles (either rejects or fulfills); 38 | * 39 | * @param onSettled called when/if "promise" settles 40 | */ 41 | finally (onSettled?: (callback: any) => U | Thenable): Promise; 42 | 43 | /** 44 | * Make a new promise from the thenable. 45 | * A thenable is promise-like in as far as it has a "then" method. 46 | */ 47 | static resolve (): Promise; 48 | static resolve (value: R | Thenable): Promise; 49 | 50 | /** 51 | * Make a promise that rejects to obj. For consistency and debugging (eg stack traces), obj should be an instanceof Error 52 | */ 53 | static reject (error: any): Promise; 54 | 55 | /** 56 | * Make a promise that fulfills when every item in the array fulfills, and rejects if (and when) any item rejects. 57 | * the array passed to all can be a mixture of promise-like objects and other objects. 58 | * The fulfillment value is an array (in order) of fulfillment values. The rejection value is the first rejection value. 59 | */ 60 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable , T5 | Thenable, T6 | Thenable, T7 | Thenable, T8 | Thenable, T9 | Thenable, T10 | Thenable]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; 61 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable , T5 | Thenable, T6 | Thenable, T7 | Thenable, T8 | Thenable, T9 | Thenable]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; 62 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable , T5 | Thenable, T6 | Thenable, T7 | Thenable, T8 | Thenable]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; 63 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable , T5 | Thenable, T6 | Thenable, T7 | Thenable]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; 64 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable , T5 | Thenable, T6 | Thenable]): Promise<[T1, T2, T3, T4, T5, T6]>; 65 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable , T5 | Thenable]): Promise<[T1, T2, T3, T4, T5]>; 66 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable, T4 | Thenable ]): Promise<[T1, T2, T3, T4]>; 67 | static all(values: [T1 | Thenable, T2 | Thenable, T3 | Thenable]): Promise<[T1, T2, T3]>; 68 | static all(values: [T1 | Thenable, T2 | Thenable]): Promise<[T1, T2]>; 69 | static all(values: [T1 | Thenable]): Promise<[T1]>; 70 | static all(values: Array>): Promise; 71 | 72 | /** 73 | * Make a Promise that fulfills when any item fulfills, and rejects if any item rejects. 74 | */ 75 | static race (promises: (R | Thenable)[]): Promise; 76 | } 77 | 78 | /** 79 | * The polyfill method will patch the global environment (in this case to the Promise name) when called. 80 | */ 81 | export function polyfill (): void; 82 | -------------------------------------------------------------------------------- /dist/es6-promise.min.js: -------------------------------------------------------------------------------- 1 | !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):t.ES6Promise=n()}(this,function(){"use strict";function t(t){return"function"==typeof t||"object"==typeof t&&null!==t}function n(t){return"function"==typeof t}function e(t){I=t}function r(t){J=t}function o(){return function(){return process.nextTick(f)}}function i(){return"undefined"!=typeof H?function(){H(f)}:c()}function s(){var t=0,n=new V(f),e=document.createTextNode("");return n.observe(e,{characterData:!0}),function(){e.data=t=++t%2}}function u(){var t=new MessageChannel;return t.port1.onmessage=f,function(){return t.port2.postMessage(0)}}function c(){var t=setTimeout;return function(){return t(f,1)}}function f(){for(var t=0;t { 50 | var sealed = false; 51 | var error = tryThen(then, thenable, value => { 52 | if (sealed) { return; } 53 | sealed = true; 54 | if (thenable !== value) { 55 | resolve(promise, value); 56 | } else { 57 | fulfill(promise, value); 58 | } 59 | }, reason => { 60 | if (sealed) { return; } 61 | sealed = true; 62 | 63 | reject(promise, reason); 64 | }, 'Settle: ' + (promise._label || ' unknown promise')); 65 | 66 | if (!sealed && error) { 67 | sealed = true; 68 | reject(promise, error); 69 | } 70 | }, promise); 71 | } 72 | 73 | function handleOwnThenable(promise, thenable) { 74 | if (thenable._state === FULFILLED) { 75 | fulfill(promise, thenable._result); 76 | } else if (thenable._state === REJECTED) { 77 | thenable._onerror = null; 78 | reject(promise, thenable._result); 79 | } else { 80 | subscribe(thenable, undefined, value => resolve(promise, value), 81 | reason => reject(promise, reason)) 82 | } 83 | } 84 | 85 | function handleMaybeThenable(promise, maybeThenable, then) { 86 | if (maybeThenable.constructor === promise.constructor && 87 | then === originalThen && 88 | maybeThenable.constructor.resolve === originalResolve) { 89 | handleOwnThenable(promise, maybeThenable); 90 | } else { 91 | if (then === GET_THEN_ERROR) { 92 | reject(promise, GET_THEN_ERROR.error); 93 | } else if (then === undefined) { 94 | fulfill(promise, maybeThenable); 95 | } else if (isFunction(then)) { 96 | handleForeignThenable(promise, maybeThenable, then); 97 | } else { 98 | fulfill(promise, maybeThenable); 99 | } 100 | } 101 | } 102 | 103 | function resolve(promise, value) { 104 | if (promise === value) { 105 | reject(promise, selfFulfillment()); 106 | } else if (objectOrFunction(value)) { 107 | handleMaybeThenable(promise, value, getThen(value)); 108 | } else { 109 | fulfill(promise, value); 110 | } 111 | } 112 | 113 | function publishRejection(promise) { 114 | if (promise._onerror) { 115 | promise._onerror(promise._result); 116 | } 117 | 118 | publish(promise); 119 | } 120 | 121 | function fulfill(promise, value) { 122 | if (promise._state !== PENDING) { return; } 123 | 124 | promise._result = value; 125 | promise._state = FULFILLED; 126 | 127 | if (promise._subscribers.length !== 0) { 128 | asap(publish, promise); 129 | } 130 | } 131 | 132 | function reject(promise, reason) { 133 | if (promise._state !== PENDING) { return; } 134 | promise._state = REJECTED; 135 | promise._result = reason; 136 | 137 | asap(publishRejection, promise); 138 | } 139 | 140 | function subscribe(parent, child, onFulfillment, onRejection) { 141 | let { _subscribers } = parent; 142 | let { length } = _subscribers; 143 | 144 | parent._onerror = null; 145 | 146 | _subscribers[length] = child; 147 | _subscribers[length + FULFILLED] = onFulfillment; 148 | _subscribers[length + REJECTED] = onRejection; 149 | 150 | if (length === 0 && parent._state) { 151 | asap(publish, parent); 152 | } 153 | } 154 | 155 | function publish(promise) { 156 | let subscribers = promise._subscribers; 157 | let settled = promise._state; 158 | 159 | if (subscribers.length === 0) { return; } 160 | 161 | let child, callback, detail = promise._result; 162 | 163 | for (let i = 0; i < subscribers.length; i += 3) { 164 | child = subscribers[i]; 165 | callback = subscribers[i + settled]; 166 | 167 | if (child) { 168 | invokeCallback(settled, child, callback, detail); 169 | } else { 170 | callback(detail); 171 | } 172 | } 173 | 174 | promise._subscribers.length = 0; 175 | } 176 | 177 | function ErrorObject() { 178 | this.error = null; 179 | } 180 | 181 | const TRY_CATCH_ERROR = new ErrorObject(); 182 | 183 | function tryCatch(callback, detail) { 184 | try { 185 | return callback(detail); 186 | } catch(e) { 187 | TRY_CATCH_ERROR.error = e; 188 | return TRY_CATCH_ERROR; 189 | } 190 | } 191 | 192 | function invokeCallback(settled, promise, callback, detail) { 193 | let hasCallback = isFunction(callback), 194 | value, error, succeeded, failed; 195 | 196 | if (hasCallback) { 197 | value = tryCatch(callback, detail); 198 | 199 | if (value === TRY_CATCH_ERROR) { 200 | failed = true; 201 | error = value.error; 202 | value = null; 203 | } else { 204 | succeeded = true; 205 | } 206 | 207 | if (promise === value) { 208 | reject(promise, cannotReturnOwn()); 209 | return; 210 | } 211 | 212 | } else { 213 | value = detail; 214 | succeeded = true; 215 | } 216 | 217 | if (promise._state !== PENDING) { 218 | // noop 219 | } else if (hasCallback && succeeded) { 220 | resolve(promise, value); 221 | } else if (failed) { 222 | reject(promise, error); 223 | } else if (settled === FULFILLED) { 224 | fulfill(promise, value); 225 | } else if (settled === REJECTED) { 226 | reject(promise, value); 227 | } 228 | } 229 | 230 | function initializePromise(promise, resolver) { 231 | try { 232 | resolver(function resolvePromise(value){ 233 | resolve(promise, value); 234 | }, function rejectPromise(reason) { 235 | reject(promise, reason); 236 | }); 237 | } catch(e) { 238 | reject(promise, e); 239 | } 240 | } 241 | 242 | let id = 0; 243 | function nextId() { 244 | return id++; 245 | } 246 | 247 | function makePromise(promise) { 248 | promise[PROMISE_ID] = id++; 249 | promise._state = undefined; 250 | promise._result = undefined; 251 | promise._subscribers = []; 252 | } 253 | 254 | export { 255 | nextId, 256 | makePromise, 257 | getThen, 258 | noop, 259 | resolve, 260 | reject, 261 | fulfill, 262 | subscribe, 263 | publish, 264 | publishRejection, 265 | initializePromise, 266 | invokeCallback, 267 | FULFILLED, 268 | REJECTED, 269 | PENDING, 270 | handleMaybeThenable 271 | }; 272 | -------------------------------------------------------------------------------- /lib/es6-promise/promise.js: -------------------------------------------------------------------------------- 1 | import { 2 | isFunction 3 | } from './utils'; 4 | 5 | import { 6 | noop, 7 | nextId, 8 | PROMISE_ID, 9 | initializePromise 10 | } from './-internal'; 11 | 12 | import { 13 | asap, 14 | setAsap, 15 | setScheduler 16 | } from './asap'; 17 | 18 | import all from './promise/all'; 19 | import race from './promise/race'; 20 | import Resolve from './promise/resolve'; 21 | import Reject from './promise/reject'; 22 | import then from './then'; 23 | 24 | 25 | function needsResolver() { 26 | throw new TypeError('You must pass a resolver function as the first argument to the promise constructor'); 27 | } 28 | 29 | function needsNew() { 30 | throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); 31 | } 32 | 33 | /** 34 | Promise objects represent the eventual result of an asynchronous operation. The 35 | primary way of interacting with a promise is through its `then` method, which 36 | registers callbacks to receive either a promise's eventual value or the reason 37 | why the promise cannot be fulfilled. 38 | 39 | Terminology 40 | ----------- 41 | 42 | - `promise` is an object or function with a `then` method whose behavior conforms to this specification. 43 | - `thenable` is an object or function that defines a `then` method. 44 | - `value` is any legal JavaScript value (including undefined, a thenable, or a promise). 45 | - `exception` is a value that is thrown using the throw statement. 46 | - `reason` is a value that indicates why a promise was rejected. 47 | - `settled` the final resting state of a promise, fulfilled or rejected. 48 | 49 | A promise can be in one of three states: pending, fulfilled, or rejected. 50 | 51 | Promises that are fulfilled have a fulfillment value and are in the fulfilled 52 | state. Promises that are rejected have a rejection reason and are in the 53 | rejected state. A fulfillment value is never a thenable. 54 | 55 | Promises can also be said to *resolve* a value. If this value is also a 56 | promise, then the original promise's settled state will match the value's 57 | settled state. So a promise that *resolves* a promise that rejects will 58 | itself reject, and a promise that *resolves* a promise that fulfills will 59 | itself fulfill. 60 | 61 | 62 | Basic Usage: 63 | ------------ 64 | 65 | ```js 66 | let promise = new Promise(function(resolve, reject) { 67 | // on success 68 | resolve(value); 69 | 70 | // on failure 71 | reject(reason); 72 | }); 73 | 74 | promise.then(function(value) { 75 | // on fulfillment 76 | }, function(reason) { 77 | // on rejection 78 | }); 79 | ``` 80 | 81 | Advanced Usage: 82 | --------------- 83 | 84 | Promises shine when abstracting away asynchronous interactions such as 85 | `XMLHttpRequest`s. 86 | 87 | ```js 88 | function getJSON(url) { 89 | return new Promise(function(resolve, reject){ 90 | let xhr = new XMLHttpRequest(); 91 | 92 | xhr.open('GET', url); 93 | xhr.onreadystatechange = handler; 94 | xhr.responseType = 'json'; 95 | xhr.setRequestHeader('Accept', 'application/json'); 96 | xhr.send(); 97 | 98 | function handler() { 99 | if (this.readyState === this.DONE) { 100 | if (this.status === 200) { 101 | resolve(this.response); 102 | } else { 103 | reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']')); 104 | } 105 | } 106 | }; 107 | }); 108 | } 109 | 110 | getJSON('/posts.json').then(function(json) { 111 | // on fulfillment 112 | }, function(reason) { 113 | // on rejection 114 | }); 115 | ``` 116 | 117 | Unlike callbacks, promises are great composable primitives. 118 | 119 | ```js 120 | Promise.all([ 121 | getJSON('/posts'), 122 | getJSON('/comments') 123 | ]).then(function(values){ 124 | values[0] // => postsJSON 125 | values[1] // => commentsJSON 126 | 127 | return values; 128 | }); 129 | ``` 130 | 131 | @class Promise 132 | @param {function} resolver 133 | Useful for tooling. 134 | @constructor 135 | */ 136 | export default function Promise(resolver) { 137 | this[PROMISE_ID] = nextId(); 138 | this._result = this._state = undefined; 139 | this._subscribers = []; 140 | 141 | if (noop !== resolver) { 142 | typeof resolver !== 'function' && needsResolver(); 143 | this instanceof Promise ? initializePromise(this, resolver) : needsNew(); 144 | } 145 | } 146 | 147 | Promise.all = all; 148 | Promise.race = race; 149 | Promise.resolve = Resolve; 150 | Promise.reject = Reject; 151 | Promise._setScheduler = setScheduler; 152 | Promise._setAsap = setAsap; 153 | Promise._asap = asap; 154 | 155 | Promise.prototype = { 156 | constructor: Promise, 157 | 158 | /** 159 | The primary way of interacting with a promise is through its `then` method, 160 | which registers callbacks to receive either a promise's eventual value or the 161 | reason why the promise cannot be fulfilled. 162 | 163 | ```js 164 | findUser().then(function(user){ 165 | // user is available 166 | }, function(reason){ 167 | // user is unavailable, and you are given the reason why 168 | }); 169 | ``` 170 | 171 | Chaining 172 | -------- 173 | 174 | The return value of `then` is itself a promise. This second, 'downstream' 175 | promise is resolved with the return value of the first promise's fulfillment 176 | or rejection handler, or rejected if the handler throws an exception. 177 | 178 | ```js 179 | findUser().then(function (user) { 180 | return user.name; 181 | }, function (reason) { 182 | return 'default name'; 183 | }).then(function (userName) { 184 | // If `findUser` fulfilled, `userName` will be the user's name, otherwise it 185 | // will be `'default name'` 186 | }); 187 | 188 | findUser().then(function (user) { 189 | throw new Error('Found user, but still unhappy'); 190 | }, function (reason) { 191 | throw new Error('`findUser` rejected and we're unhappy'); 192 | }).then(function (value) { 193 | // never reached 194 | }, function (reason) { 195 | // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. 196 | // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. 197 | }); 198 | ``` 199 | If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. 200 | 201 | ```js 202 | findUser().then(function (user) { 203 | throw new PedagogicalException('Upstream error'); 204 | }).then(function (value) { 205 | // never reached 206 | }).then(function (value) { 207 | // never reached 208 | }, function (reason) { 209 | // The `PedgagocialException` is propagated all the way down to here 210 | }); 211 | ``` 212 | 213 | Assimilation 214 | ------------ 215 | 216 | Sometimes the value you want to propagate to a downstream promise can only be 217 | retrieved asynchronously. This can be achieved by returning a promise in the 218 | fulfillment or rejection handler. The downstream promise will then be pending 219 | until the returned promise is settled. This is called *assimilation*. 220 | 221 | ```js 222 | findUser().then(function (user) { 223 | return findCommentsByAuthor(user); 224 | }).then(function (comments) { 225 | // The user's comments are now available 226 | }); 227 | ``` 228 | 229 | If the assimliated promise rejects, then the downstream promise will also reject. 230 | 231 | ```js 232 | findUser().then(function (user) { 233 | return findCommentsByAuthor(user); 234 | }).then(function (comments) { 235 | // If `findCommentsByAuthor` fulfills, we'll have the value here 236 | }, function (reason) { 237 | // If `findCommentsByAuthor` rejects, we'll have the reason here 238 | }); 239 | ``` 240 | 241 | Simple Example 242 | -------------- 243 | 244 | Synchronous Example 245 | 246 | ```javascript 247 | let result; 248 | 249 | try { 250 | result = findResult(); 251 | // success 252 | } catch(reason) { 253 | // failure 254 | } 255 | ``` 256 | 257 | Errback Example 258 | 259 | ```js 260 | findResult(function(result, err){ 261 | if (err) { 262 | // failure 263 | } else { 264 | // success 265 | } 266 | }); 267 | ``` 268 | 269 | Promise Example; 270 | 271 | ```javascript 272 | findResult().then(function(result){ 273 | // success 274 | }, function(reason){ 275 | // failure 276 | }); 277 | ``` 278 | 279 | Advanced Example 280 | -------------- 281 | 282 | Synchronous Example 283 | 284 | ```javascript 285 | let author, books; 286 | 287 | try { 288 | author = findAuthor(); 289 | books = findBooksByAuthor(author); 290 | // success 291 | } catch(reason) { 292 | // failure 293 | } 294 | ``` 295 | 296 | Errback Example 297 | 298 | ```js 299 | 300 | function foundBooks(books) { 301 | 302 | } 303 | 304 | function failure(reason) { 305 | 306 | } 307 | 308 | findAuthor(function(author, err){ 309 | if (err) { 310 | failure(err); 311 | // failure 312 | } else { 313 | try { 314 | findBoooksByAuthor(author, function(books, err) { 315 | if (err) { 316 | failure(err); 317 | } else { 318 | try { 319 | foundBooks(books); 320 | } catch(reason) { 321 | failure(reason); 322 | } 323 | } 324 | }); 325 | } catch(error) { 326 | failure(err); 327 | } 328 | // success 329 | } 330 | }); 331 | ``` 332 | 333 | Promise Example; 334 | 335 | ```javascript 336 | findAuthor(). 337 | then(findBooksByAuthor). 338 | then(function(books){ 339 | // found books 340 | }).catch(function(reason){ 341 | // something went wrong 342 | }); 343 | ``` 344 | 345 | @method then 346 | @param {Function} onFulfilled 347 | @param {Function} onRejected 348 | Useful for tooling. 349 | @return {Promise} 350 | */ 351 | then: then, 352 | 353 | /** 354 | `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same 355 | as the catch block of a try/catch statement. 356 | 357 | ```js 358 | function findAuthor(){ 359 | throw new Error('couldn't find that author'); 360 | } 361 | 362 | // synchronous 363 | try { 364 | findAuthor(); 365 | } catch(reason) { 366 | // something went wrong 367 | } 368 | 369 | // async with promises 370 | findAuthor().catch(function(reason){ 371 | // something went wrong 372 | }); 373 | ``` 374 | 375 | @method catch 376 | @param {Function} onRejection 377 | Useful for tooling. 378 | @return {Promise} 379 | */ 380 | catch(onRejection) { 381 | return this.then(null, onRejection); 382 | }, 383 | 384 | 385 | /** 386 | `finally` will be invoked regardless of the promise's fate just as native 387 | try/catch/finally behaves 388 | 389 | Synchronous example: 390 | 391 | ```js 392 | findAuthor() { 393 | if (Math.random() > 0.5) { 394 | throw new Error(); 395 | } 396 | return new Author(); 397 | } 398 | 399 | try { 400 | return findAuthor(); // succeed or fail 401 | } catch(error) { 402 | return findOtherAuthor(); 403 | } finally { 404 | // always runs 405 | // doesn't affect the return value 406 | } 407 | ``` 408 | 409 | Asynchronous example: 410 | 411 | ```js 412 | findAuthor().catch(function(reason){ 413 | return findOtherAuthor(); 414 | }).finally(function(){ 415 | // author was either found, or not 416 | }); 417 | ``` 418 | 419 | @method finally 420 | @param {Function} callback 421 | @param {String} label optional string for labeling the promise. 422 | Useful for tooling. 423 | @return {Promise} 424 | */ 425 | finally(callback, label) { 426 | let promise = this; 427 | let constructor = promise.constructor; 428 | 429 | return promise.then(value => constructor.resolve(callback()).then(() => value), 430 | reason => constructor.resolve(callback()).then(() => { throw reason; })); 431 | }, 432 | 433 | // Ported from RSVP.js 434 | _onerror(reason) { 435 | let promise = this; 436 | setTimeout(() => { 437 | if (promise._onerror && typeof Promise.onerror === 'function') { 438 | Promise.onerror(reason); 439 | } 440 | }, 0); 441 | }, 442 | }; 443 | -------------------------------------------------------------------------------- /dist/es6-promise-polyfill.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["config/versionTemplate.txt","es6-promise-polyfill.js"],"sourcesContent":["/*!\n * @overview es6-promise - a tiny implementation of Promises/A+ (fork by Dropbox).\n * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)\n * @license Licensed under MIT license\n * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE\n * @repo https://github.com/dropbox/es6-promise\n * @version 4.0.5+fd5149c8\n */\n","var Promise = (function () {\n'use strict';\n\nfunction objectOrFunction(x) {\n return typeof x === 'function' || typeof x === 'object' && x !== null;\n}\n\nfunction isFunction(x) {\n return typeof x === 'function';\n}\n\nvar _isArray = undefined;\nif (!Array.isArray) {\n _isArray = function (x) {\n return Object.prototype.toString.call(x) === '[object Array]';\n };\n} else {\n _isArray = Array.isArray;\n}\n\nvar isArray = _isArray;\n\nvar len = 0;\nvar vertxNext = undefined;\nvar customSchedulerFn = undefined;\n\nvar asap = function asap(callback, arg) {\n queue[len] = callback;\n queue[len + 1] = arg;\n len += 2;\n if (len === 2) {\n // If len is 2, that means that we need to schedule an async flush.\n // If additional callbacks are queued before the queue is flushed, they\n // will be processed by this flush that we are scheduling.\n if (customSchedulerFn) {\n customSchedulerFn(flush);\n } else {\n scheduleFlush();\n }\n }\n};\n\nfunction setScheduler(scheduleFn) {\n customSchedulerFn = scheduleFn;\n}\n\nfunction setAsap(asapFn) {\n asap = asapFn;\n}\n\nvar browserWindow = typeof window !== 'undefined' ? window : undefined;\nvar browserGlobal = browserWindow || {};\nvar BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;\nvar isNode = typeof self === 'undefined' && typeof process !== 'undefined' && ({}).toString.call(process) === '[object process]';\n\n// test for web worker but not in IE10\nvar isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';\n\n// node\nfunction useNextTick() {\n // node version 0.10.x displays a deprecation warning when nextTick is used recursively\n // see https://github.com/cujojs/when/issues/410 for details\n return function () {\n return process.nextTick(flush);\n };\n}\n\n// vertx\nfunction useVertxTimer() {\n if (typeof vertxNext !== 'undefined') {\n return function () {\n vertxNext(flush);\n };\n }\n\n return useSetTimeout();\n}\n\nfunction useMutationObserver() {\n var iterations = 0;\n var observer = new BrowserMutationObserver(flush);\n var node = document.createTextNode('');\n observer.observe(node, { characterData: true });\n\n return function () {\n node.data = iterations = ++iterations % 2;\n };\n}\n\n// web worker\nfunction useMessageChannel() {\n var channel = new MessageChannel();\n channel.port1.onmessage = flush;\n return function () {\n return channel.port2.postMessage(0);\n };\n}\n\nfunction useSetTimeout() {\n // Store setTimeout reference so es6-promise will be unaffected by\n // other code modifying setTimeout (like sinon.useFakeTimers())\n var globalSetTimeout = setTimeout;\n return function () {\n return globalSetTimeout(flush, 1);\n };\n}\n\nvar queue = new Array(1000);\nfunction flush() {\n for (var i = 0; i < len; i += 2) {\n var callback = queue[i];\n var arg = queue[i + 1];\n\n callback(arg);\n\n queue[i] = undefined;\n queue[i + 1] = undefined;\n }\n\n len = 0;\n}\n\nfunction attemptVertx() {\n try {\n var r = require;\n var vertx = r('vertx');\n vertxNext = vertx.runOnLoop || vertx.runOnContext;\n return useVertxTimer();\n } catch (e) {\n return useSetTimeout();\n }\n}\n\nvar scheduleFlush = undefined;\n// Decide what async method to use to triggering processing of queued callbacks:\nif (isNode) {\n scheduleFlush = useNextTick();\n} else if (BrowserMutationObserver) {\n scheduleFlush = useMutationObserver();\n} else if (isWorker) {\n scheduleFlush = useMessageChannel();\n} else if (browserWindow === undefined && typeof require === 'function') {\n scheduleFlush = attemptVertx();\n} else {\n scheduleFlush = useSetTimeout();\n}\n\nfunction then(onFulfillment, onRejection) {\n var _arguments = arguments;\n\n var parent = this;\n\n parent._onerror = null;\n\n var child = new this.constructor(noop);\n\n if (child[PROMISE_ID] === undefined) {\n makePromise(child);\n }\n\n var _state = parent._state;\n\n if (_state) {\n (function () {\n var callback = _arguments[_state - 1];\n asap(function () {\n return invokeCallback(_state, child, callback, parent._result);\n });\n })();\n } else {\n subscribe(parent, child, onFulfillment, onRejection);\n }\n\n return child;\n}\n\n/**\n `Promise.resolve` returns a promise that will become resolved with the\n passed `value`. It is shorthand for the following:\n\n ```javascript\n let promise = new Promise(function(resolve, reject){\n resolve(1);\n });\n\n promise.then(function(value){\n // value === 1\n });\n ```\n\n Instead of writing the above, your code now simply becomes the following:\n\n ```javascript\n let promise = Promise.resolve(1);\n\n promise.then(function(value){\n // value === 1\n });\n ```\n\n @method resolve\n @static\n @param {Any} value value that the returned promise will be resolved with\n Useful for tooling.\n @return {Promise} a promise that will become fulfilled with the given\n `value`\n*/\nfunction resolve(object) {\n /*jshint validthis:true */\n var Constructor = this;\n\n if (object && typeof object === 'object' && object.constructor === Constructor) {\n return object;\n }\n\n var promise = new Constructor(noop);\n _resolve(promise, object);\n return promise;\n}\n\nvar PROMISE_ID = Math.random().toString(36).substring(16);\n\nfunction noop() {}\n\nvar PENDING = void 0;\nvar FULFILLED = 1;\nvar REJECTED = 2;\n\nvar GET_THEN_ERROR = new ErrorObject();\n\nfunction selfFulfillment() {\n return new TypeError(\"You cannot resolve a promise with itself\");\n}\n\nfunction cannotReturnOwn() {\n return new TypeError('A promises callback cannot return that same promise.');\n}\n\nfunction getThen(promise) {\n try {\n return promise.then;\n } catch (error) {\n GET_THEN_ERROR.error = error;\n return GET_THEN_ERROR;\n }\n}\n\nfunction tryThen(then, value, fulfillmentHandler, rejectionHandler) {\n try {\n then.call(value, fulfillmentHandler, rejectionHandler);\n } catch (e) {\n return e;\n }\n}\n\nfunction handleForeignThenable(promise, thenable, then) {\n asap(function (promise) {\n var sealed = false;\n var error = tryThen(then, thenable, function (value) {\n if (sealed) {\n return;\n }\n sealed = true;\n if (thenable !== value) {\n _resolve(promise, value);\n } else {\n fulfill(promise, value);\n }\n }, function (reason) {\n if (sealed) {\n return;\n }\n sealed = true;\n\n _reject(promise, reason);\n }, 'Settle: ' + (promise._label || ' unknown promise'));\n\n if (!sealed && error) {\n sealed = true;\n _reject(promise, error);\n }\n }, promise);\n}\n\nfunction handleOwnThenable(promise, thenable) {\n if (thenable._state === FULFILLED) {\n fulfill(promise, thenable._result);\n } else if (thenable._state === REJECTED) {\n thenable._onerror = null;\n _reject(promise, thenable._result);\n } else {\n subscribe(thenable, undefined, function (value) {\n return _resolve(promise, value);\n }, function (reason) {\n return _reject(promise, reason);\n });\n }\n}\n\nfunction handleMaybeThenable(promise, maybeThenable, then$$) {\n if (maybeThenable.constructor === promise.constructor && then$$ === then && maybeThenable.constructor.resolve === resolve) {\n handleOwnThenable(promise, maybeThenable);\n } else {\n if (then$$ === GET_THEN_ERROR) {\n _reject(promise, GET_THEN_ERROR.error);\n } else if (then$$ === undefined) {\n fulfill(promise, maybeThenable);\n } else if (isFunction(then$$)) {\n handleForeignThenable(promise, maybeThenable, then$$);\n } else {\n fulfill(promise, maybeThenable);\n }\n }\n}\n\nfunction _resolve(promise, value) {\n if (promise === value) {\n _reject(promise, selfFulfillment());\n } else if (objectOrFunction(value)) {\n handleMaybeThenable(promise, value, getThen(value));\n } else {\n fulfill(promise, value);\n }\n}\n\nfunction publishRejection(promise) {\n if (promise._onerror) {\n promise._onerror(promise._result);\n }\n\n publish(promise);\n}\n\nfunction fulfill(promise, value) {\n if (promise._state !== PENDING) {\n return;\n }\n\n promise._result = value;\n promise._state = FULFILLED;\n\n if (promise._subscribers.length !== 0) {\n asap(publish, promise);\n }\n}\n\nfunction _reject(promise, reason) {\n if (promise._state !== PENDING) {\n return;\n }\n promise._state = REJECTED;\n promise._result = reason;\n\n asap(publishRejection, promise);\n}\n\nfunction subscribe(parent, child, onFulfillment, onRejection) {\n var _subscribers = parent._subscribers;\n var length = _subscribers.length;\n\n parent._onerror = null;\n\n _subscribers[length] = child;\n _subscribers[length + FULFILLED] = onFulfillment;\n _subscribers[length + REJECTED] = onRejection;\n\n if (length === 0 && parent._state) {\n asap(publish, parent);\n }\n}\n\nfunction publish(promise) {\n var subscribers = promise._subscribers;\n var settled = promise._state;\n\n if (subscribers.length === 0) {\n return;\n }\n\n var child = undefined,\n callback = undefined,\n detail = promise._result;\n\n for (var i = 0; i < subscribers.length; i += 3) {\n child = subscribers[i];\n callback = subscribers[i + settled];\n\n if (child) {\n invokeCallback(settled, child, callback, detail);\n } else {\n callback(detail);\n }\n }\n\n promise._subscribers.length = 0;\n}\n\nfunction ErrorObject() {\n this.error = null;\n}\n\nvar TRY_CATCH_ERROR = new ErrorObject();\n\nfunction tryCatch(callback, detail) {\n try {\n return callback(detail);\n } catch (e) {\n TRY_CATCH_ERROR.error = e;\n return TRY_CATCH_ERROR;\n }\n}\n\nfunction invokeCallback(settled, promise, callback, detail) {\n var hasCallback = isFunction(callback),\n value = undefined,\n error = undefined,\n succeeded = undefined,\n failed = undefined;\n\n if (hasCallback) {\n value = tryCatch(callback, detail);\n\n if (value === TRY_CATCH_ERROR) {\n failed = true;\n error = value.error;\n value = null;\n } else {\n succeeded = true;\n }\n\n if (promise === value) {\n _reject(promise, cannotReturnOwn());\n return;\n }\n } else {\n value = detail;\n succeeded = true;\n }\n\n if (promise._state !== PENDING) {\n // noop\n } else if (hasCallback && succeeded) {\n _resolve(promise, value);\n } else if (failed) {\n _reject(promise, error);\n } else if (settled === FULFILLED) {\n fulfill(promise, value);\n } else if (settled === REJECTED) {\n _reject(promise, value);\n }\n}\n\nfunction initializePromise(promise, resolver) {\n try {\n resolver(function resolvePromise(value) {\n _resolve(promise, value);\n }, function rejectPromise(reason) {\n _reject(promise, reason);\n });\n } catch (e) {\n _reject(promise, e);\n }\n}\n\nvar id = 0;\nfunction nextId() {\n return id++;\n}\n\nfunction makePromise(promise) {\n promise[PROMISE_ID] = id++;\n promise._state = undefined;\n promise._result = undefined;\n promise._subscribers = [];\n}\n\nfunction Enumerator(Constructor, input) {\n this._instanceConstructor = Constructor;\n this.promise = new Constructor(noop);\n\n if (!this.promise[PROMISE_ID]) {\n makePromise(this.promise);\n }\n\n if (isArray(input)) {\n this._input = input;\n this.length = input.length;\n this._remaining = input.length;\n\n this._result = new Array(this.length);\n\n if (this.length === 0) {\n fulfill(this.promise, this._result);\n } else {\n this.length = this.length || 0;\n this._enumerate();\n if (this._remaining === 0) {\n fulfill(this.promise, this._result);\n }\n }\n } else {\n _reject(this.promise, validationError());\n }\n}\n\nfunction validationError() {\n return new Error('Array Methods must be provided an Array');\n};\n\nEnumerator.prototype._enumerate = function () {\n var length = this.length;\n var _input = this._input;\n\n for (var i = 0; this._state === PENDING && i < length; i++) {\n this._eachEntry(_input[i], i);\n }\n};\n\nEnumerator.prototype._eachEntry = function (entry, i) {\n var c = this._instanceConstructor;\n var resolve$$ = c.resolve;\n\n if (resolve$$ === resolve) {\n var _then = getThen(entry);\n\n if (_then === then && entry._state !== PENDING) {\n entry._onerror = null;\n this._settledAt(entry._state, i, entry._result);\n } else if (typeof _then !== 'function') {\n this._remaining--;\n this._result[i] = entry;\n } else if (c === Promise) {\n var promise = new c(noop);\n handleMaybeThenable(promise, entry, _then);\n this._willSettleAt(promise, i);\n } else {\n this._willSettleAt(new c(function (resolve$$) {\n return resolve$$(entry);\n }), i);\n }\n } else {\n this._willSettleAt(resolve$$(entry), i);\n }\n};\n\nEnumerator.prototype._settledAt = function (state, i, value) {\n var promise = this.promise;\n\n if (promise._state === PENDING) {\n this._remaining--;\n\n if (state === REJECTED) {\n _reject(promise, value);\n } else {\n this._result[i] = value;\n }\n }\n\n if (this._remaining === 0) {\n fulfill(promise, this._result);\n }\n};\n\nEnumerator.prototype._willSettleAt = function (promise, i) {\n var enumerator = this;\n\n subscribe(promise, undefined, function (value) {\n return enumerator._settledAt(FULFILLED, i, value);\n }, function (reason) {\n return enumerator._settledAt(REJECTED, i, reason);\n });\n};\n\n/**\n `Promise.all` accepts an array of promises, and returns a new promise which\n is fulfilled with an array of fulfillment values for the passed promises, or\n rejected with the reason of the first passed promise to be rejected. It casts all\n elements of the passed iterable to promises as it runs this algorithm.\n\n Example:\n\n ```javascript\n let promise1 = resolve(1);\n let promise2 = resolve(2);\n let promise3 = resolve(3);\n let promises = [ promise1, promise2, promise3 ];\n\n Promise.all(promises).then(function(array){\n // The array here would be [ 1, 2, 3 ];\n });\n ```\n\n If any of the `promises` given to `all` are rejected, the first promise\n that is rejected will be given as an argument to the returned promises's\n rejection handler. For example:\n\n Example:\n\n ```javascript\n let promise1 = resolve(1);\n let promise2 = reject(new Error(\"2\"));\n let promise3 = reject(new Error(\"3\"));\n let promises = [ promise1, promise2, promise3 ];\n\n Promise.all(promises).then(function(array){\n // Code here never runs because there are rejected promises!\n }, function(error) {\n // error.message === \"2\"\n });\n ```\n\n @method all\n @static\n @param {Array} entries array of promises\n @param {String} label optional string for labeling the promise.\n Useful for tooling.\n @return {Promise} promise that is fulfilled when all `promises` have been\n fulfilled, or rejected if any of them become rejected.\n @static\n*/\nfunction all(entries) {\n return new Enumerator(this, entries).promise;\n}\n\n/**\n `Promise.race` returns a new promise which is settled in the same way as the\n first passed promise to settle.\n\n Example:\n\n ```javascript\n let promise1 = new Promise(function(resolve, reject){\n setTimeout(function(){\n resolve('promise 1');\n }, 200);\n });\n\n let promise2 = new Promise(function(resolve, reject){\n setTimeout(function(){\n resolve('promise 2');\n }, 100);\n });\n\n Promise.race([promise1, promise2]).then(function(result){\n // result === 'promise 2' because it was resolved before promise1\n // was resolved.\n });\n ```\n\n `Promise.race` is deterministic in that only the state of the first\n settled promise matters. For example, even if other promises given to the\n `promises` array argument are resolved, but the first settled promise has\n become rejected before the other promises became fulfilled, the returned\n promise will become rejected:\n\n ```javascript\n let promise1 = new Promise(function(resolve, reject){\n setTimeout(function(){\n resolve('promise 1');\n }, 200);\n });\n\n let promise2 = new Promise(function(resolve, reject){\n setTimeout(function(){\n reject(new Error('promise 2'));\n }, 100);\n });\n\n Promise.race([promise1, promise2]).then(function(result){\n // Code here never runs\n }, function(reason){\n // reason.message === 'promise 2' because promise 2 became rejected before\n // promise 1 became fulfilled\n });\n ```\n\n An example real-world use case is implementing timeouts:\n\n ```javascript\n Promise.race([ajax('foo.json'), timeout(5000)])\n ```\n\n @method race\n @static\n @param {Array} promises array of promises to observe\n Useful for tooling.\n @return {Promise} a promise which settles in the same way as the first passed\n promise to settle.\n*/\nfunction race(entries) {\n /*jshint validthis:true */\n var Constructor = this;\n\n if (!isArray(entries)) {\n return new Constructor(function (_, reject) {\n return reject(new TypeError('You must pass an array to race.'));\n });\n } else {\n return new Constructor(function (resolve, reject) {\n var length = entries.length;\n for (var i = 0; i < length; i++) {\n Constructor.resolve(entries[i]).then(resolve, reject);\n }\n });\n }\n}\n\n/**\n `Promise.reject` returns a promise rejected with the passed `reason`.\n It is shorthand for the following:\n\n ```javascript\n let promise = new Promise(function(resolve, reject){\n reject(new Error('WHOOPS'));\n });\n\n promise.then(function(value){\n // Code here doesn't run because the promise is rejected!\n }, function(reason){\n // reason.message === 'WHOOPS'\n });\n ```\n\n Instead of writing the above, your code now simply becomes the following:\n\n ```javascript\n let promise = Promise.reject(new Error('WHOOPS'));\n\n promise.then(function(value){\n // Code here doesn't run because the promise is rejected!\n }, function(reason){\n // reason.message === 'WHOOPS'\n });\n ```\n\n @method reject\n @static\n @param {Any} reason value that the returned promise will be rejected with.\n Useful for tooling.\n @return {Promise} a promise rejected with the given `reason`.\n*/\nfunction reject(reason) {\n /*jshint validthis:true */\n var Constructor = this;\n var promise = new Constructor(noop);\n _reject(promise, reason);\n return promise;\n}\n\nfunction needsResolver() {\n throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');\n}\n\nfunction needsNew() {\n throw new TypeError(\"Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.\");\n}\n\n/**\n Promise objects represent the eventual result of an asynchronous operation. The\n primary way of interacting with a promise is through its `then` method, which\n registers callbacks to receive either a promise's eventual value or the reason\n why the promise cannot be fulfilled.\n\n Terminology\n -----------\n\n - `promise` is an object or function with a `then` method whose behavior conforms to this specification.\n - `thenable` is an object or function that defines a `then` method.\n - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).\n - `exception` is a value that is thrown using the throw statement.\n - `reason` is a value that indicates why a promise was rejected.\n - `settled` the final resting state of a promise, fulfilled or rejected.\n\n A promise can be in one of three states: pending, fulfilled, or rejected.\n\n Promises that are fulfilled have a fulfillment value and are in the fulfilled\n state. Promises that are rejected have a rejection reason and are in the\n rejected state. A fulfillment value is never a thenable.\n\n Promises can also be said to *resolve* a value. If this value is also a\n promise, then the original promise's settled state will match the value's\n settled state. So a promise that *resolves* a promise that rejects will\n itself reject, and a promise that *resolves* a promise that fulfills will\n itself fulfill.\n\n\n Basic Usage:\n ------------\n\n ```js\n let promise = new Promise(function(resolve, reject) {\n // on success\n resolve(value);\n\n // on failure\n reject(reason);\n });\n\n promise.then(function(value) {\n // on fulfillment\n }, function(reason) {\n // on rejection\n });\n ```\n\n Advanced Usage:\n ---------------\n\n Promises shine when abstracting away asynchronous interactions such as\n `XMLHttpRequest`s.\n\n ```js\n function getJSON(url) {\n return new Promise(function(resolve, reject){\n let xhr = new XMLHttpRequest();\n\n xhr.open('GET', url);\n xhr.onreadystatechange = handler;\n xhr.responseType = 'json';\n xhr.setRequestHeader('Accept', 'application/json');\n xhr.send();\n\n function handler() {\n if (this.readyState === this.DONE) {\n if (this.status === 200) {\n resolve(this.response);\n } else {\n reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));\n }\n }\n };\n });\n }\n\n getJSON('/posts.json').then(function(json) {\n // on fulfillment\n }, function(reason) {\n // on rejection\n });\n ```\n\n Unlike callbacks, promises are great composable primitives.\n\n ```js\n Promise.all([\n getJSON('/posts'),\n getJSON('/comments')\n ]).then(function(values){\n values[0] // => postsJSON\n values[1] // => commentsJSON\n\n return values;\n });\n ```\n\n @class Promise\n @param {function} resolver\n Useful for tooling.\n @constructor\n*/\nfunction Promise(resolver) {\n this[PROMISE_ID] = nextId();\n this._result = this._state = undefined;\n this._subscribers = [];\n\n if (noop !== resolver) {\n typeof resolver !== 'function' && needsResolver();\n this instanceof Promise ? initializePromise(this, resolver) : needsNew();\n }\n}\n\nPromise.all = all;\nPromise.race = race;\nPromise.resolve = resolve;\nPromise.reject = reject;\nPromise._setScheduler = setScheduler;\nPromise._setAsap = setAsap;\nPromise._asap = asap;\n\nPromise.prototype = {\n constructor: Promise,\n\n /**\n The primary way of interacting with a promise is through its `then` method,\n which registers callbacks to receive either a promise's eventual value or the\n reason why the promise cannot be fulfilled.\n \n ```js\n findUser().then(function(user){\n // user is available\n }, function(reason){\n // user is unavailable, and you are given the reason why\n });\n ```\n \n Chaining\n --------\n \n The return value of `then` is itself a promise. This second, 'downstream'\n promise is resolved with the return value of the first promise's fulfillment\n or rejection handler, or rejected if the handler throws an exception.\n \n ```js\n findUser().then(function (user) {\n return user.name;\n }, function (reason) {\n return 'default name';\n }).then(function (userName) {\n // If `findUser` fulfilled, `userName` will be the user's name, otherwise it\n // will be `'default name'`\n });\n \n findUser().then(function (user) {\n throw new Error('Found user, but still unhappy');\n }, function (reason) {\n throw new Error('`findUser` rejected and we're unhappy');\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.\n // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.\n });\n ```\n If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.\n \n ```js\n findUser().then(function (user) {\n throw new PedagogicalException('Upstream error');\n }).then(function (value) {\n // never reached\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // The `PedgagocialException` is propagated all the way down to here\n });\n ```\n \n Assimilation\n ------------\n \n Sometimes the value you want to propagate to a downstream promise can only be\n retrieved asynchronously. This can be achieved by returning a promise in the\n fulfillment or rejection handler. The downstream promise will then be pending\n until the returned promise is settled. This is called *assimilation*.\n \n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // The user's comments are now available\n });\n ```\n \n If the assimliated promise rejects, then the downstream promise will also reject.\n \n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // If `findCommentsByAuthor` fulfills, we'll have the value here\n }, function (reason) {\n // If `findCommentsByAuthor` rejects, we'll have the reason here\n });\n ```\n \n Simple Example\n --------------\n \n Synchronous Example\n \n ```javascript\n let result;\n \n try {\n result = findResult();\n // success\n } catch(reason) {\n // failure\n }\n ```\n \n Errback Example\n \n ```js\n findResult(function(result, err){\n if (err) {\n // failure\n } else {\n // success\n }\n });\n ```\n \n Promise Example;\n \n ```javascript\n findResult().then(function(result){\n // success\n }, function(reason){\n // failure\n });\n ```\n \n Advanced Example\n --------------\n \n Synchronous Example\n \n ```javascript\n let author, books;\n \n try {\n author = findAuthor();\n books = findBooksByAuthor(author);\n // success\n } catch(reason) {\n // failure\n }\n ```\n \n Errback Example\n \n ```js\n \n function foundBooks(books) {\n \n }\n \n function failure(reason) {\n \n }\n \n findAuthor(function(author, err){\n if (err) {\n failure(err);\n // failure\n } else {\n try {\n findBoooksByAuthor(author, function(books, err) {\n if (err) {\n failure(err);\n } else {\n try {\n foundBooks(books);\n } catch(reason) {\n failure(reason);\n }\n }\n });\n } catch(error) {\n failure(err);\n }\n // success\n }\n });\n ```\n \n Promise Example;\n \n ```javascript\n findAuthor().\n then(findBooksByAuthor).\n then(function(books){\n // found books\n }).catch(function(reason){\n // something went wrong\n });\n ```\n \n @method then\n @param {Function} onFulfilled\n @param {Function} onRejected\n Useful for tooling.\n @return {Promise}\n */\n then: then,\n\n /**\n `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same\n as the catch block of a try/catch statement.\n \n ```js\n function findAuthor(){\n throw new Error('couldn't find that author');\n }\n \n // synchronous\n try {\n findAuthor();\n } catch(reason) {\n // something went wrong\n }\n \n // async with promises\n findAuthor().catch(function(reason){\n // something went wrong\n });\n ```\n \n @method catch\n @param {Function} onRejection\n Useful for tooling.\n @return {Promise}\n */\n 'catch': function _catch(onRejection) {\n return this.then(null, onRejection);\n },\n\n /**\n `finally` will be invoked regardless of the promise's fate just as native\n try/catch/finally behaves\n \n Synchronous example:\n \n ```js\n findAuthor() {\n if (Math.random() > 0.5) {\n throw new Error();\n }\n return new Author();\n }\n \n try {\n return findAuthor(); // succeed or fail\n } catch(error) {\n return findOtherAuthor();\n } finally {\n // always runs\n // doesn't affect the return value\n }\n ```\n \n Asynchronous example:\n \n ```js\n findAuthor().catch(function(reason){\n return findOtherAuthor();\n }).finally(function(){\n // author was either found, or not\n });\n ```\n \n @method finally\n @param {Function} callback\n @param {String} label optional string for labeling the promise.\n Useful for tooling.\n @return {Promise}\n */\n 'finally': function _finally(callback, label) {\n var promise = this;\n var constructor = promise.constructor;\n\n return promise.then(function (value) {\n return constructor.resolve(callback()).then(function () {\n return value;\n });\n }, function (reason) {\n return constructor.resolve(callback()).then(function () {\n throw reason;\n });\n });\n },\n\n // Ported from RSVP.js\n _onerror: function _onerror(reason) {\n var promise = this;\n setTimeout(function () {\n if (promise._onerror && typeof Promise.onerror === 'function') {\n Promise.onerror(reason);\n }\n }, 0);\n }\n};\n\nreturn Promise;\n\n}());"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;","file":"es6-promise-polyfill.js"} -------------------------------------------------------------------------------- /dist/es6-promise-polyfill.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * @overview es6-promise - a tiny implementation of Promises/A+ (fork by Dropbox). 3 | * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) 4 | * @license Licensed under MIT license 5 | * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE 6 | * @repo https://github.com/dropbox/es6-promise 7 | * @version 4.0.5+fd5149c8 8 | */ 9 | 10 | var Promise = (function () { 11 | 'use strict'; 12 | 13 | function objectOrFunction(x) { 14 | return typeof x === 'function' || typeof x === 'object' && x !== null; 15 | } 16 | 17 | function isFunction(x) { 18 | return typeof x === 'function'; 19 | } 20 | 21 | var _isArray = undefined; 22 | if (!Array.isArray) { 23 | _isArray = function (x) { 24 | return Object.prototype.toString.call(x) === '[object Array]'; 25 | }; 26 | } else { 27 | _isArray = Array.isArray; 28 | } 29 | 30 | var isArray = _isArray; 31 | 32 | var len = 0; 33 | var vertxNext = undefined; 34 | var customSchedulerFn = undefined; 35 | 36 | var asap = function asap(callback, arg) { 37 | queue[len] = callback; 38 | queue[len + 1] = arg; 39 | len += 2; 40 | if (len === 2) { 41 | // If len is 2, that means that we need to schedule an async flush. 42 | // If additional callbacks are queued before the queue is flushed, they 43 | // will be processed by this flush that we are scheduling. 44 | if (customSchedulerFn) { 45 | customSchedulerFn(flush); 46 | } else { 47 | scheduleFlush(); 48 | } 49 | } 50 | }; 51 | 52 | function setScheduler(scheduleFn) { 53 | customSchedulerFn = scheduleFn; 54 | } 55 | 56 | function setAsap(asapFn) { 57 | asap = asapFn; 58 | } 59 | 60 | var browserWindow = typeof window !== 'undefined' ? window : undefined; 61 | var browserGlobal = browserWindow || {}; 62 | var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; 63 | var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && ({}).toString.call(process) === '[object process]'; 64 | 65 | // test for web worker but not in IE10 66 | var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined'; 67 | 68 | // node 69 | function useNextTick() { 70 | // node version 0.10.x displays a deprecation warning when nextTick is used recursively 71 | // see https://github.com/cujojs/when/issues/410 for details 72 | return function () { 73 | return process.nextTick(flush); 74 | }; 75 | } 76 | 77 | // vertx 78 | function useVertxTimer() { 79 | if (typeof vertxNext !== 'undefined') { 80 | return function () { 81 | vertxNext(flush); 82 | }; 83 | } 84 | 85 | return useSetTimeout(); 86 | } 87 | 88 | function useMutationObserver() { 89 | var iterations = 0; 90 | var observer = new BrowserMutationObserver(flush); 91 | var node = document.createTextNode(''); 92 | observer.observe(node, { characterData: true }); 93 | 94 | return function () { 95 | node.data = iterations = ++iterations % 2; 96 | }; 97 | } 98 | 99 | // web worker 100 | function useMessageChannel() { 101 | var channel = new MessageChannel(); 102 | channel.port1.onmessage = flush; 103 | return function () { 104 | return channel.port2.postMessage(0); 105 | }; 106 | } 107 | 108 | function useSetTimeout() { 109 | // Store setTimeout reference so es6-promise will be unaffected by 110 | // other code modifying setTimeout (like sinon.useFakeTimers()) 111 | var globalSetTimeout = setTimeout; 112 | return function () { 113 | return globalSetTimeout(flush, 1); 114 | }; 115 | } 116 | 117 | var queue = new Array(1000); 118 | function flush() { 119 | for (var i = 0; i < len; i += 2) { 120 | var callback = queue[i]; 121 | var arg = queue[i + 1]; 122 | 123 | callback(arg); 124 | 125 | queue[i] = undefined; 126 | queue[i + 1] = undefined; 127 | } 128 | 129 | len = 0; 130 | } 131 | 132 | function attemptVertx() { 133 | try { 134 | var r = require; 135 | var vertx = r('vertx'); 136 | vertxNext = vertx.runOnLoop || vertx.runOnContext; 137 | return useVertxTimer(); 138 | } catch (e) { 139 | return useSetTimeout(); 140 | } 141 | } 142 | 143 | var scheduleFlush = undefined; 144 | // Decide what async method to use to triggering processing of queued callbacks: 145 | if (isNode) { 146 | scheduleFlush = useNextTick(); 147 | } else if (BrowserMutationObserver) { 148 | scheduleFlush = useMutationObserver(); 149 | } else if (isWorker) { 150 | scheduleFlush = useMessageChannel(); 151 | } else if (browserWindow === undefined && typeof require === 'function') { 152 | scheduleFlush = attemptVertx(); 153 | } else { 154 | scheduleFlush = useSetTimeout(); 155 | } 156 | 157 | function then(onFulfillment, onRejection) { 158 | var _arguments = arguments; 159 | 160 | var parent = this; 161 | 162 | parent._onerror = null; 163 | 164 | var child = new this.constructor(noop); 165 | 166 | if (child[PROMISE_ID] === undefined) { 167 | makePromise(child); 168 | } 169 | 170 | var _state = parent._state; 171 | 172 | if (_state) { 173 | (function () { 174 | var callback = _arguments[_state - 1]; 175 | asap(function () { 176 | return invokeCallback(_state, child, callback, parent._result); 177 | }); 178 | })(); 179 | } else { 180 | subscribe(parent, child, onFulfillment, onRejection); 181 | } 182 | 183 | return child; 184 | } 185 | 186 | /** 187 | `Promise.resolve` returns a promise that will become resolved with the 188 | passed `value`. It is shorthand for the following: 189 | 190 | ```javascript 191 | let promise = new Promise(function(resolve, reject){ 192 | resolve(1); 193 | }); 194 | 195 | promise.then(function(value){ 196 | // value === 1 197 | }); 198 | ``` 199 | 200 | Instead of writing the above, your code now simply becomes the following: 201 | 202 | ```javascript 203 | let promise = Promise.resolve(1); 204 | 205 | promise.then(function(value){ 206 | // value === 1 207 | }); 208 | ``` 209 | 210 | @method resolve 211 | @static 212 | @param {Any} value value that the returned promise will be resolved with 213 | Useful for tooling. 214 | @return {Promise} a promise that will become fulfilled with the given 215 | `value` 216 | */ 217 | function resolve(object) { 218 | /*jshint validthis:true */ 219 | var Constructor = this; 220 | 221 | if (object && typeof object === 'object' && object.constructor === Constructor) { 222 | return object; 223 | } 224 | 225 | var promise = new Constructor(noop); 226 | _resolve(promise, object); 227 | return promise; 228 | } 229 | 230 | var PROMISE_ID = Math.random().toString(36).substring(16); 231 | 232 | function noop() {} 233 | 234 | var PENDING = void 0; 235 | var FULFILLED = 1; 236 | var REJECTED = 2; 237 | 238 | var GET_THEN_ERROR = new ErrorObject(); 239 | 240 | function selfFulfillment() { 241 | return new TypeError("You cannot resolve a promise with itself"); 242 | } 243 | 244 | function cannotReturnOwn() { 245 | return new TypeError('A promises callback cannot return that same promise.'); 246 | } 247 | 248 | function getThen(promise) { 249 | try { 250 | return promise.then; 251 | } catch (error) { 252 | GET_THEN_ERROR.error = error; 253 | return GET_THEN_ERROR; 254 | } 255 | } 256 | 257 | function tryThen(then, value, fulfillmentHandler, rejectionHandler) { 258 | try { 259 | then.call(value, fulfillmentHandler, rejectionHandler); 260 | } catch (e) { 261 | return e; 262 | } 263 | } 264 | 265 | function handleForeignThenable(promise, thenable, then) { 266 | asap(function (promise) { 267 | var sealed = false; 268 | var error = tryThen(then, thenable, function (value) { 269 | if (sealed) { 270 | return; 271 | } 272 | sealed = true; 273 | if (thenable !== value) { 274 | _resolve(promise, value); 275 | } else { 276 | fulfill(promise, value); 277 | } 278 | }, function (reason) { 279 | if (sealed) { 280 | return; 281 | } 282 | sealed = true; 283 | 284 | _reject(promise, reason); 285 | }, 'Settle: ' + (promise._label || ' unknown promise')); 286 | 287 | if (!sealed && error) { 288 | sealed = true; 289 | _reject(promise, error); 290 | } 291 | }, promise); 292 | } 293 | 294 | function handleOwnThenable(promise, thenable) { 295 | if (thenable._state === FULFILLED) { 296 | fulfill(promise, thenable._result); 297 | } else if (thenable._state === REJECTED) { 298 | thenable._onerror = null; 299 | _reject(promise, thenable._result); 300 | } else { 301 | subscribe(thenable, undefined, function (value) { 302 | return _resolve(promise, value); 303 | }, function (reason) { 304 | return _reject(promise, reason); 305 | }); 306 | } 307 | } 308 | 309 | function handleMaybeThenable(promise, maybeThenable, then$$) { 310 | if (maybeThenable.constructor === promise.constructor && then$$ === then && maybeThenable.constructor.resolve === resolve) { 311 | handleOwnThenable(promise, maybeThenable); 312 | } else { 313 | if (then$$ === GET_THEN_ERROR) { 314 | _reject(promise, GET_THEN_ERROR.error); 315 | } else if (then$$ === undefined) { 316 | fulfill(promise, maybeThenable); 317 | } else if (isFunction(then$$)) { 318 | handleForeignThenable(promise, maybeThenable, then$$); 319 | } else { 320 | fulfill(promise, maybeThenable); 321 | } 322 | } 323 | } 324 | 325 | function _resolve(promise, value) { 326 | if (promise === value) { 327 | _reject(promise, selfFulfillment()); 328 | } else if (objectOrFunction(value)) { 329 | handleMaybeThenable(promise, value, getThen(value)); 330 | } else { 331 | fulfill(promise, value); 332 | } 333 | } 334 | 335 | function publishRejection(promise) { 336 | if (promise._onerror) { 337 | promise._onerror(promise._result); 338 | } 339 | 340 | publish(promise); 341 | } 342 | 343 | function fulfill(promise, value) { 344 | if (promise._state !== PENDING) { 345 | return; 346 | } 347 | 348 | promise._result = value; 349 | promise._state = FULFILLED; 350 | 351 | if (promise._subscribers.length !== 0) { 352 | asap(publish, promise); 353 | } 354 | } 355 | 356 | function _reject(promise, reason) { 357 | if (promise._state !== PENDING) { 358 | return; 359 | } 360 | promise._state = REJECTED; 361 | promise._result = reason; 362 | 363 | asap(publishRejection, promise); 364 | } 365 | 366 | function subscribe(parent, child, onFulfillment, onRejection) { 367 | var _subscribers = parent._subscribers; 368 | var length = _subscribers.length; 369 | 370 | parent._onerror = null; 371 | 372 | _subscribers[length] = child; 373 | _subscribers[length + FULFILLED] = onFulfillment; 374 | _subscribers[length + REJECTED] = onRejection; 375 | 376 | if (length === 0 && parent._state) { 377 | asap(publish, parent); 378 | } 379 | } 380 | 381 | function publish(promise) { 382 | var subscribers = promise._subscribers; 383 | var settled = promise._state; 384 | 385 | if (subscribers.length === 0) { 386 | return; 387 | } 388 | 389 | var child = undefined, 390 | callback = undefined, 391 | detail = promise._result; 392 | 393 | for (var i = 0; i < subscribers.length; i += 3) { 394 | child = subscribers[i]; 395 | callback = subscribers[i + settled]; 396 | 397 | if (child) { 398 | invokeCallback(settled, child, callback, detail); 399 | } else { 400 | callback(detail); 401 | } 402 | } 403 | 404 | promise._subscribers.length = 0; 405 | } 406 | 407 | function ErrorObject() { 408 | this.error = null; 409 | } 410 | 411 | var TRY_CATCH_ERROR = new ErrorObject(); 412 | 413 | function tryCatch(callback, detail) { 414 | try { 415 | return callback(detail); 416 | } catch (e) { 417 | TRY_CATCH_ERROR.error = e; 418 | return TRY_CATCH_ERROR; 419 | } 420 | } 421 | 422 | function invokeCallback(settled, promise, callback, detail) { 423 | var hasCallback = isFunction(callback), 424 | value = undefined, 425 | error = undefined, 426 | succeeded = undefined, 427 | failed = undefined; 428 | 429 | if (hasCallback) { 430 | value = tryCatch(callback, detail); 431 | 432 | if (value === TRY_CATCH_ERROR) { 433 | failed = true; 434 | error = value.error; 435 | value = null; 436 | } else { 437 | succeeded = true; 438 | } 439 | 440 | if (promise === value) { 441 | _reject(promise, cannotReturnOwn()); 442 | return; 443 | } 444 | } else { 445 | value = detail; 446 | succeeded = true; 447 | } 448 | 449 | if (promise._state !== PENDING) { 450 | // noop 451 | } else if (hasCallback && succeeded) { 452 | _resolve(promise, value); 453 | } else if (failed) { 454 | _reject(promise, error); 455 | } else if (settled === FULFILLED) { 456 | fulfill(promise, value); 457 | } else if (settled === REJECTED) { 458 | _reject(promise, value); 459 | } 460 | } 461 | 462 | function initializePromise(promise, resolver) { 463 | try { 464 | resolver(function resolvePromise(value) { 465 | _resolve(promise, value); 466 | }, function rejectPromise(reason) { 467 | _reject(promise, reason); 468 | }); 469 | } catch (e) { 470 | _reject(promise, e); 471 | } 472 | } 473 | 474 | var id = 0; 475 | function nextId() { 476 | return id++; 477 | } 478 | 479 | function makePromise(promise) { 480 | promise[PROMISE_ID] = id++; 481 | promise._state = undefined; 482 | promise._result = undefined; 483 | promise._subscribers = []; 484 | } 485 | 486 | function Enumerator(Constructor, input) { 487 | this._instanceConstructor = Constructor; 488 | this.promise = new Constructor(noop); 489 | 490 | if (!this.promise[PROMISE_ID]) { 491 | makePromise(this.promise); 492 | } 493 | 494 | if (isArray(input)) { 495 | this._input = input; 496 | this.length = input.length; 497 | this._remaining = input.length; 498 | 499 | this._result = new Array(this.length); 500 | 501 | if (this.length === 0) { 502 | fulfill(this.promise, this._result); 503 | } else { 504 | this.length = this.length || 0; 505 | this._enumerate(); 506 | if (this._remaining === 0) { 507 | fulfill(this.promise, this._result); 508 | } 509 | } 510 | } else { 511 | _reject(this.promise, validationError()); 512 | } 513 | } 514 | 515 | function validationError() { 516 | return new Error('Array Methods must be provided an Array'); 517 | }; 518 | 519 | Enumerator.prototype._enumerate = function () { 520 | var length = this.length; 521 | var _input = this._input; 522 | 523 | for (var i = 0; this._state === PENDING && i < length; i++) { 524 | this._eachEntry(_input[i], i); 525 | } 526 | }; 527 | 528 | Enumerator.prototype._eachEntry = function (entry, i) { 529 | var c = this._instanceConstructor; 530 | var resolve$$ = c.resolve; 531 | 532 | if (resolve$$ === resolve) { 533 | var _then = getThen(entry); 534 | 535 | if (_then === then && entry._state !== PENDING) { 536 | entry._onerror = null; 537 | this._settledAt(entry._state, i, entry._result); 538 | } else if (typeof _then !== 'function') { 539 | this._remaining--; 540 | this._result[i] = entry; 541 | } else if (c === Promise) { 542 | var promise = new c(noop); 543 | handleMaybeThenable(promise, entry, _then); 544 | this._willSettleAt(promise, i); 545 | } else { 546 | this._willSettleAt(new c(function (resolve$$) { 547 | return resolve$$(entry); 548 | }), i); 549 | } 550 | } else { 551 | this._willSettleAt(resolve$$(entry), i); 552 | } 553 | }; 554 | 555 | Enumerator.prototype._settledAt = function (state, i, value) { 556 | var promise = this.promise; 557 | 558 | if (promise._state === PENDING) { 559 | this._remaining--; 560 | 561 | if (state === REJECTED) { 562 | _reject(promise, value); 563 | } else { 564 | this._result[i] = value; 565 | } 566 | } 567 | 568 | if (this._remaining === 0) { 569 | fulfill(promise, this._result); 570 | } 571 | }; 572 | 573 | Enumerator.prototype._willSettleAt = function (promise, i) { 574 | var enumerator = this; 575 | 576 | subscribe(promise, undefined, function (value) { 577 | return enumerator._settledAt(FULFILLED, i, value); 578 | }, function (reason) { 579 | return enumerator._settledAt(REJECTED, i, reason); 580 | }); 581 | }; 582 | 583 | /** 584 | `Promise.all` accepts an array of promises, and returns a new promise which 585 | is fulfilled with an array of fulfillment values for the passed promises, or 586 | rejected with the reason of the first passed promise to be rejected. It casts all 587 | elements of the passed iterable to promises as it runs this algorithm. 588 | 589 | Example: 590 | 591 | ```javascript 592 | let promise1 = resolve(1); 593 | let promise2 = resolve(2); 594 | let promise3 = resolve(3); 595 | let promises = [ promise1, promise2, promise3 ]; 596 | 597 | Promise.all(promises).then(function(array){ 598 | // The array here would be [ 1, 2, 3 ]; 599 | }); 600 | ``` 601 | 602 | If any of the `promises` given to `all` are rejected, the first promise 603 | that is rejected will be given as an argument to the returned promises's 604 | rejection handler. For example: 605 | 606 | Example: 607 | 608 | ```javascript 609 | let promise1 = resolve(1); 610 | let promise2 = reject(new Error("2")); 611 | let promise3 = reject(new Error("3")); 612 | let promises = [ promise1, promise2, promise3 ]; 613 | 614 | Promise.all(promises).then(function(array){ 615 | // Code here never runs because there are rejected promises! 616 | }, function(error) { 617 | // error.message === "2" 618 | }); 619 | ``` 620 | 621 | @method all 622 | @static 623 | @param {Array} entries array of promises 624 | @param {String} label optional string for labeling the promise. 625 | Useful for tooling. 626 | @return {Promise} promise that is fulfilled when all `promises` have been 627 | fulfilled, or rejected if any of them become rejected. 628 | @static 629 | */ 630 | function all(entries) { 631 | return new Enumerator(this, entries).promise; 632 | } 633 | 634 | /** 635 | `Promise.race` returns a new promise which is settled in the same way as the 636 | first passed promise to settle. 637 | 638 | Example: 639 | 640 | ```javascript 641 | let promise1 = new Promise(function(resolve, reject){ 642 | setTimeout(function(){ 643 | resolve('promise 1'); 644 | }, 200); 645 | }); 646 | 647 | let promise2 = new Promise(function(resolve, reject){ 648 | setTimeout(function(){ 649 | resolve('promise 2'); 650 | }, 100); 651 | }); 652 | 653 | Promise.race([promise1, promise2]).then(function(result){ 654 | // result === 'promise 2' because it was resolved before promise1 655 | // was resolved. 656 | }); 657 | ``` 658 | 659 | `Promise.race` is deterministic in that only the state of the first 660 | settled promise matters. For example, even if other promises given to the 661 | `promises` array argument are resolved, but the first settled promise has 662 | become rejected before the other promises became fulfilled, the returned 663 | promise will become rejected: 664 | 665 | ```javascript 666 | let promise1 = new Promise(function(resolve, reject){ 667 | setTimeout(function(){ 668 | resolve('promise 1'); 669 | }, 200); 670 | }); 671 | 672 | let promise2 = new Promise(function(resolve, reject){ 673 | setTimeout(function(){ 674 | reject(new Error('promise 2')); 675 | }, 100); 676 | }); 677 | 678 | Promise.race([promise1, promise2]).then(function(result){ 679 | // Code here never runs 680 | }, function(reason){ 681 | // reason.message === 'promise 2' because promise 2 became rejected before 682 | // promise 1 became fulfilled 683 | }); 684 | ``` 685 | 686 | An example real-world use case is implementing timeouts: 687 | 688 | ```javascript 689 | Promise.race([ajax('foo.json'), timeout(5000)]) 690 | ``` 691 | 692 | @method race 693 | @static 694 | @param {Array} promises array of promises to observe 695 | Useful for tooling. 696 | @return {Promise} a promise which settles in the same way as the first passed 697 | promise to settle. 698 | */ 699 | function race(entries) { 700 | /*jshint validthis:true */ 701 | var Constructor = this; 702 | 703 | if (!isArray(entries)) { 704 | return new Constructor(function (_, reject) { 705 | return reject(new TypeError('You must pass an array to race.')); 706 | }); 707 | } else { 708 | return new Constructor(function (resolve, reject) { 709 | var length = entries.length; 710 | for (var i = 0; i < length; i++) { 711 | Constructor.resolve(entries[i]).then(resolve, reject); 712 | } 713 | }); 714 | } 715 | } 716 | 717 | /** 718 | `Promise.reject` returns a promise rejected with the passed `reason`. 719 | It is shorthand for the following: 720 | 721 | ```javascript 722 | let promise = new Promise(function(resolve, reject){ 723 | reject(new Error('WHOOPS')); 724 | }); 725 | 726 | promise.then(function(value){ 727 | // Code here doesn't run because the promise is rejected! 728 | }, function(reason){ 729 | // reason.message === 'WHOOPS' 730 | }); 731 | ``` 732 | 733 | Instead of writing the above, your code now simply becomes the following: 734 | 735 | ```javascript 736 | let promise = Promise.reject(new Error('WHOOPS')); 737 | 738 | promise.then(function(value){ 739 | // Code here doesn't run because the promise is rejected! 740 | }, function(reason){ 741 | // reason.message === 'WHOOPS' 742 | }); 743 | ``` 744 | 745 | @method reject 746 | @static 747 | @param {Any} reason value that the returned promise will be rejected with. 748 | Useful for tooling. 749 | @return {Promise} a promise rejected with the given `reason`. 750 | */ 751 | function reject(reason) { 752 | /*jshint validthis:true */ 753 | var Constructor = this; 754 | var promise = new Constructor(noop); 755 | _reject(promise, reason); 756 | return promise; 757 | } 758 | 759 | function needsResolver() { 760 | throw new TypeError('You must pass a resolver function as the first argument to the promise constructor'); 761 | } 762 | 763 | function needsNew() { 764 | throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); 765 | } 766 | 767 | /** 768 | Promise objects represent the eventual result of an asynchronous operation. The 769 | primary way of interacting with a promise is through its `then` method, which 770 | registers callbacks to receive either a promise's eventual value or the reason 771 | why the promise cannot be fulfilled. 772 | 773 | Terminology 774 | ----------- 775 | 776 | - `promise` is an object or function with a `then` method whose behavior conforms to this specification. 777 | - `thenable` is an object or function that defines a `then` method. 778 | - `value` is any legal JavaScript value (including undefined, a thenable, or a promise). 779 | - `exception` is a value that is thrown using the throw statement. 780 | - `reason` is a value that indicates why a promise was rejected. 781 | - `settled` the final resting state of a promise, fulfilled or rejected. 782 | 783 | A promise can be in one of three states: pending, fulfilled, or rejected. 784 | 785 | Promises that are fulfilled have a fulfillment value and are in the fulfilled 786 | state. Promises that are rejected have a rejection reason and are in the 787 | rejected state. A fulfillment value is never a thenable. 788 | 789 | Promises can also be said to *resolve* a value. If this value is also a 790 | promise, then the original promise's settled state will match the value's 791 | settled state. So a promise that *resolves* a promise that rejects will 792 | itself reject, and a promise that *resolves* a promise that fulfills will 793 | itself fulfill. 794 | 795 | 796 | Basic Usage: 797 | ------------ 798 | 799 | ```js 800 | let promise = new Promise(function(resolve, reject) { 801 | // on success 802 | resolve(value); 803 | 804 | // on failure 805 | reject(reason); 806 | }); 807 | 808 | promise.then(function(value) { 809 | // on fulfillment 810 | }, function(reason) { 811 | // on rejection 812 | }); 813 | ``` 814 | 815 | Advanced Usage: 816 | --------------- 817 | 818 | Promises shine when abstracting away asynchronous interactions such as 819 | `XMLHttpRequest`s. 820 | 821 | ```js 822 | function getJSON(url) { 823 | return new Promise(function(resolve, reject){ 824 | let xhr = new XMLHttpRequest(); 825 | 826 | xhr.open('GET', url); 827 | xhr.onreadystatechange = handler; 828 | xhr.responseType = 'json'; 829 | xhr.setRequestHeader('Accept', 'application/json'); 830 | xhr.send(); 831 | 832 | function handler() { 833 | if (this.readyState === this.DONE) { 834 | if (this.status === 200) { 835 | resolve(this.response); 836 | } else { 837 | reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']')); 838 | } 839 | } 840 | }; 841 | }); 842 | } 843 | 844 | getJSON('/posts.json').then(function(json) { 845 | // on fulfillment 846 | }, function(reason) { 847 | // on rejection 848 | }); 849 | ``` 850 | 851 | Unlike callbacks, promises are great composable primitives. 852 | 853 | ```js 854 | Promise.all([ 855 | getJSON('/posts'), 856 | getJSON('/comments') 857 | ]).then(function(values){ 858 | values[0] // => postsJSON 859 | values[1] // => commentsJSON 860 | 861 | return values; 862 | }); 863 | ``` 864 | 865 | @class Promise 866 | @param {function} resolver 867 | Useful for tooling. 868 | @constructor 869 | */ 870 | function Promise(resolver) { 871 | this[PROMISE_ID] = nextId(); 872 | this._result = this._state = undefined; 873 | this._subscribers = []; 874 | 875 | if (noop !== resolver) { 876 | typeof resolver !== 'function' && needsResolver(); 877 | this instanceof Promise ? initializePromise(this, resolver) : needsNew(); 878 | } 879 | } 880 | 881 | Promise.all = all; 882 | Promise.race = race; 883 | Promise.resolve = resolve; 884 | Promise.reject = reject; 885 | Promise._setScheduler = setScheduler; 886 | Promise._setAsap = setAsap; 887 | Promise._asap = asap; 888 | 889 | Promise.prototype = { 890 | constructor: Promise, 891 | 892 | /** 893 | The primary way of interacting with a promise is through its `then` method, 894 | which registers callbacks to receive either a promise's eventual value or the 895 | reason why the promise cannot be fulfilled. 896 | 897 | ```js 898 | findUser().then(function(user){ 899 | // user is available 900 | }, function(reason){ 901 | // user is unavailable, and you are given the reason why 902 | }); 903 | ``` 904 | 905 | Chaining 906 | -------- 907 | 908 | The return value of `then` is itself a promise. This second, 'downstream' 909 | promise is resolved with the return value of the first promise's fulfillment 910 | or rejection handler, or rejected if the handler throws an exception. 911 | 912 | ```js 913 | findUser().then(function (user) { 914 | return user.name; 915 | }, function (reason) { 916 | return 'default name'; 917 | }).then(function (userName) { 918 | // If `findUser` fulfilled, `userName` will be the user's name, otherwise it 919 | // will be `'default name'` 920 | }); 921 | 922 | findUser().then(function (user) { 923 | throw new Error('Found user, but still unhappy'); 924 | }, function (reason) { 925 | throw new Error('`findUser` rejected and we're unhappy'); 926 | }).then(function (value) { 927 | // never reached 928 | }, function (reason) { 929 | // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. 930 | // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. 931 | }); 932 | ``` 933 | If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. 934 | 935 | ```js 936 | findUser().then(function (user) { 937 | throw new PedagogicalException('Upstream error'); 938 | }).then(function (value) { 939 | // never reached 940 | }).then(function (value) { 941 | // never reached 942 | }, function (reason) { 943 | // The `PedgagocialException` is propagated all the way down to here 944 | }); 945 | ``` 946 | 947 | Assimilation 948 | ------------ 949 | 950 | Sometimes the value you want to propagate to a downstream promise can only be 951 | retrieved asynchronously. This can be achieved by returning a promise in the 952 | fulfillment or rejection handler. The downstream promise will then be pending 953 | until the returned promise is settled. This is called *assimilation*. 954 | 955 | ```js 956 | findUser().then(function (user) { 957 | return findCommentsByAuthor(user); 958 | }).then(function (comments) { 959 | // The user's comments are now available 960 | }); 961 | ``` 962 | 963 | If the assimliated promise rejects, then the downstream promise will also reject. 964 | 965 | ```js 966 | findUser().then(function (user) { 967 | return findCommentsByAuthor(user); 968 | }).then(function (comments) { 969 | // If `findCommentsByAuthor` fulfills, we'll have the value here 970 | }, function (reason) { 971 | // If `findCommentsByAuthor` rejects, we'll have the reason here 972 | }); 973 | ``` 974 | 975 | Simple Example 976 | -------------- 977 | 978 | Synchronous Example 979 | 980 | ```javascript 981 | let result; 982 | 983 | try { 984 | result = findResult(); 985 | // success 986 | } catch(reason) { 987 | // failure 988 | } 989 | ``` 990 | 991 | Errback Example 992 | 993 | ```js 994 | findResult(function(result, err){ 995 | if (err) { 996 | // failure 997 | } else { 998 | // success 999 | } 1000 | }); 1001 | ``` 1002 | 1003 | Promise Example; 1004 | 1005 | ```javascript 1006 | findResult().then(function(result){ 1007 | // success 1008 | }, function(reason){ 1009 | // failure 1010 | }); 1011 | ``` 1012 | 1013 | Advanced Example 1014 | -------------- 1015 | 1016 | Synchronous Example 1017 | 1018 | ```javascript 1019 | let author, books; 1020 | 1021 | try { 1022 | author = findAuthor(); 1023 | books = findBooksByAuthor(author); 1024 | // success 1025 | } catch(reason) { 1026 | // failure 1027 | } 1028 | ``` 1029 | 1030 | Errback Example 1031 | 1032 | ```js 1033 | 1034 | function foundBooks(books) { 1035 | 1036 | } 1037 | 1038 | function failure(reason) { 1039 | 1040 | } 1041 | 1042 | findAuthor(function(author, err){ 1043 | if (err) { 1044 | failure(err); 1045 | // failure 1046 | } else { 1047 | try { 1048 | findBoooksByAuthor(author, function(books, err) { 1049 | if (err) { 1050 | failure(err); 1051 | } else { 1052 | try { 1053 | foundBooks(books); 1054 | } catch(reason) { 1055 | failure(reason); 1056 | } 1057 | } 1058 | }); 1059 | } catch(error) { 1060 | failure(err); 1061 | } 1062 | // success 1063 | } 1064 | }); 1065 | ``` 1066 | 1067 | Promise Example; 1068 | 1069 | ```javascript 1070 | findAuthor(). 1071 | then(findBooksByAuthor). 1072 | then(function(books){ 1073 | // found books 1074 | }).catch(function(reason){ 1075 | // something went wrong 1076 | }); 1077 | ``` 1078 | 1079 | @method then 1080 | @param {Function} onFulfilled 1081 | @param {Function} onRejected 1082 | Useful for tooling. 1083 | @return {Promise} 1084 | */ 1085 | then: then, 1086 | 1087 | /** 1088 | `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same 1089 | as the catch block of a try/catch statement. 1090 | 1091 | ```js 1092 | function findAuthor(){ 1093 | throw new Error('couldn't find that author'); 1094 | } 1095 | 1096 | // synchronous 1097 | try { 1098 | findAuthor(); 1099 | } catch(reason) { 1100 | // something went wrong 1101 | } 1102 | 1103 | // async with promises 1104 | findAuthor().catch(function(reason){ 1105 | // something went wrong 1106 | }); 1107 | ``` 1108 | 1109 | @method catch 1110 | @param {Function} onRejection 1111 | Useful for tooling. 1112 | @return {Promise} 1113 | */ 1114 | 'catch': function _catch(onRejection) { 1115 | return this.then(null, onRejection); 1116 | }, 1117 | 1118 | /** 1119 | `finally` will be invoked regardless of the promise's fate just as native 1120 | try/catch/finally behaves 1121 | 1122 | Synchronous example: 1123 | 1124 | ```js 1125 | findAuthor() { 1126 | if (Math.random() > 0.5) { 1127 | throw new Error(); 1128 | } 1129 | return new Author(); 1130 | } 1131 | 1132 | try { 1133 | return findAuthor(); // succeed or fail 1134 | } catch(error) { 1135 | return findOtherAuthor(); 1136 | } finally { 1137 | // always runs 1138 | // doesn't affect the return value 1139 | } 1140 | ``` 1141 | 1142 | Asynchronous example: 1143 | 1144 | ```js 1145 | findAuthor().catch(function(reason){ 1146 | return findOtherAuthor(); 1147 | }).finally(function(){ 1148 | // author was either found, or not 1149 | }); 1150 | ``` 1151 | 1152 | @method finally 1153 | @param {Function} callback 1154 | @param {String} label optional string for labeling the promise. 1155 | Useful for tooling. 1156 | @return {Promise} 1157 | */ 1158 | 'finally': function _finally(callback, label) { 1159 | var promise = this; 1160 | var constructor = promise.constructor; 1161 | 1162 | return promise.then(function (value) { 1163 | return constructor.resolve(callback()).then(function () { 1164 | return value; 1165 | }); 1166 | }, function (reason) { 1167 | return constructor.resolve(callback()).then(function () { 1168 | throw reason; 1169 | }); 1170 | }); 1171 | }, 1172 | 1173 | // Ported from RSVP.js 1174 | _onerror: function _onerror(reason) { 1175 | var promise = this; 1176 | setTimeout(function () { 1177 | if (promise._onerror && typeof Promise.onerror === 'function') { 1178 | Promise.onerror(reason); 1179 | } 1180 | }, 0); 1181 | } 1182 | }; 1183 | 1184 | return Promise; 1185 | 1186 | }());//# sourceMappingURL=es6-promise-polyfill.map 1187 | -------------------------------------------------------------------------------- /dist/es6-promise.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * @overview es6-promise - a tiny implementation of Promises/A+ (fork by Dropbox). 3 | * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) 4 | * @license Licensed under MIT license 5 | * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE 6 | * @repo https://github.com/dropbox/es6-promise 7 | * @version 4.0.5+fd5149c8 8 | */ 9 | 10 | (function (global, factory) { 11 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 12 | typeof define === 'function' && define.amd ? define(factory) : 13 | (global.ES6Promise = factory()); 14 | }(this, (function () { 'use strict'; 15 | 16 | function objectOrFunction(x) { 17 | return typeof x === 'function' || typeof x === 'object' && x !== null; 18 | } 19 | 20 | function isFunction(x) { 21 | return typeof x === 'function'; 22 | } 23 | 24 | var _isArray = undefined; 25 | if (!Array.isArray) { 26 | _isArray = function (x) { 27 | return Object.prototype.toString.call(x) === '[object Array]'; 28 | }; 29 | } else { 30 | _isArray = Array.isArray; 31 | } 32 | 33 | var isArray = _isArray; 34 | 35 | var len = 0; 36 | var vertxNext = undefined; 37 | var customSchedulerFn = undefined; 38 | 39 | var asap = function asap(callback, arg) { 40 | queue[len] = callback; 41 | queue[len + 1] = arg; 42 | len += 2; 43 | if (len === 2) { 44 | // If len is 2, that means that we need to schedule an async flush. 45 | // If additional callbacks are queued before the queue is flushed, they 46 | // will be processed by this flush that we are scheduling. 47 | if (customSchedulerFn) { 48 | customSchedulerFn(flush); 49 | } else { 50 | scheduleFlush(); 51 | } 52 | } 53 | }; 54 | 55 | function setScheduler(scheduleFn) { 56 | customSchedulerFn = scheduleFn; 57 | } 58 | 59 | function setAsap(asapFn) { 60 | asap = asapFn; 61 | } 62 | 63 | var browserWindow = typeof window !== 'undefined' ? window : undefined; 64 | var browserGlobal = browserWindow || {}; 65 | var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; 66 | var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && ({}).toString.call(process) === '[object process]'; 67 | 68 | // test for web worker but not in IE10 69 | var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined'; 70 | 71 | // node 72 | function useNextTick() { 73 | // node version 0.10.x displays a deprecation warning when nextTick is used recursively 74 | // see https://github.com/cujojs/when/issues/410 for details 75 | return function () { 76 | return process.nextTick(flush); 77 | }; 78 | } 79 | 80 | // vertx 81 | function useVertxTimer() { 82 | if (typeof vertxNext !== 'undefined') { 83 | return function () { 84 | vertxNext(flush); 85 | }; 86 | } 87 | 88 | return useSetTimeout(); 89 | } 90 | 91 | function useMutationObserver() { 92 | var iterations = 0; 93 | var observer = new BrowserMutationObserver(flush); 94 | var node = document.createTextNode(''); 95 | observer.observe(node, { characterData: true }); 96 | 97 | return function () { 98 | node.data = iterations = ++iterations % 2; 99 | }; 100 | } 101 | 102 | // web worker 103 | function useMessageChannel() { 104 | var channel = new MessageChannel(); 105 | channel.port1.onmessage = flush; 106 | return function () { 107 | return channel.port2.postMessage(0); 108 | }; 109 | } 110 | 111 | function useSetTimeout() { 112 | // Store setTimeout reference so es6-promise will be unaffected by 113 | // other code modifying setTimeout (like sinon.useFakeTimers()) 114 | var globalSetTimeout = setTimeout; 115 | return function () { 116 | return globalSetTimeout(flush, 1); 117 | }; 118 | } 119 | 120 | var queue = new Array(1000); 121 | function flush() { 122 | for (var i = 0; i < len; i += 2) { 123 | var callback = queue[i]; 124 | var arg = queue[i + 1]; 125 | 126 | callback(arg); 127 | 128 | queue[i] = undefined; 129 | queue[i + 1] = undefined; 130 | } 131 | 132 | len = 0; 133 | } 134 | 135 | function attemptVertx() { 136 | try { 137 | var r = require; 138 | var vertx = r('vertx'); 139 | vertxNext = vertx.runOnLoop || vertx.runOnContext; 140 | return useVertxTimer(); 141 | } catch (e) { 142 | return useSetTimeout(); 143 | } 144 | } 145 | 146 | var scheduleFlush = undefined; 147 | // Decide what async method to use to triggering processing of queued callbacks: 148 | if (isNode) { 149 | scheduleFlush = useNextTick(); 150 | } else if (BrowserMutationObserver) { 151 | scheduleFlush = useMutationObserver(); 152 | } else if (isWorker) { 153 | scheduleFlush = useMessageChannel(); 154 | } else if (browserWindow === undefined && typeof require === 'function') { 155 | scheduleFlush = attemptVertx(); 156 | } else { 157 | scheduleFlush = useSetTimeout(); 158 | } 159 | 160 | function then(onFulfillment, onRejection) { 161 | var _arguments = arguments; 162 | 163 | var parent = this; 164 | 165 | parent._onerror = null; 166 | 167 | var child = new this.constructor(noop); 168 | 169 | if (child[PROMISE_ID] === undefined) { 170 | makePromise(child); 171 | } 172 | 173 | var _state = parent._state; 174 | 175 | if (_state) { 176 | (function () { 177 | var callback = _arguments[_state - 1]; 178 | asap(function () { 179 | return invokeCallback(_state, child, callback, parent._result); 180 | }); 181 | })(); 182 | } else { 183 | subscribe(parent, child, onFulfillment, onRejection); 184 | } 185 | 186 | return child; 187 | } 188 | 189 | /** 190 | `Promise.resolve` returns a promise that will become resolved with the 191 | passed `value`. It is shorthand for the following: 192 | 193 | ```javascript 194 | let promise = new Promise(function(resolve, reject){ 195 | resolve(1); 196 | }); 197 | 198 | promise.then(function(value){ 199 | // value === 1 200 | }); 201 | ``` 202 | 203 | Instead of writing the above, your code now simply becomes the following: 204 | 205 | ```javascript 206 | let promise = Promise.resolve(1); 207 | 208 | promise.then(function(value){ 209 | // value === 1 210 | }); 211 | ``` 212 | 213 | @method resolve 214 | @static 215 | @param {Any} value value that the returned promise will be resolved with 216 | Useful for tooling. 217 | @return {Promise} a promise that will become fulfilled with the given 218 | `value` 219 | */ 220 | function resolve(object) { 221 | /*jshint validthis:true */ 222 | var Constructor = this; 223 | 224 | if (object && typeof object === 'object' && object.constructor === Constructor) { 225 | return object; 226 | } 227 | 228 | var promise = new Constructor(noop); 229 | _resolve(promise, object); 230 | return promise; 231 | } 232 | 233 | var PROMISE_ID = Math.random().toString(36).substring(16); 234 | 235 | function noop() {} 236 | 237 | var PENDING = void 0; 238 | var FULFILLED = 1; 239 | var REJECTED = 2; 240 | 241 | var GET_THEN_ERROR = new ErrorObject(); 242 | 243 | function selfFulfillment() { 244 | return new TypeError("You cannot resolve a promise with itself"); 245 | } 246 | 247 | function cannotReturnOwn() { 248 | return new TypeError('A promises callback cannot return that same promise.'); 249 | } 250 | 251 | function getThen(promise) { 252 | try { 253 | return promise.then; 254 | } catch (error) { 255 | GET_THEN_ERROR.error = error; 256 | return GET_THEN_ERROR; 257 | } 258 | } 259 | 260 | function tryThen(then, value, fulfillmentHandler, rejectionHandler) { 261 | try { 262 | then.call(value, fulfillmentHandler, rejectionHandler); 263 | } catch (e) { 264 | return e; 265 | } 266 | } 267 | 268 | function handleForeignThenable(promise, thenable, then) { 269 | asap(function (promise) { 270 | var sealed = false; 271 | var error = tryThen(then, thenable, function (value) { 272 | if (sealed) { 273 | return; 274 | } 275 | sealed = true; 276 | if (thenable !== value) { 277 | _resolve(promise, value); 278 | } else { 279 | fulfill(promise, value); 280 | } 281 | }, function (reason) { 282 | if (sealed) { 283 | return; 284 | } 285 | sealed = true; 286 | 287 | _reject(promise, reason); 288 | }, 'Settle: ' + (promise._label || ' unknown promise')); 289 | 290 | if (!sealed && error) { 291 | sealed = true; 292 | _reject(promise, error); 293 | } 294 | }, promise); 295 | } 296 | 297 | function handleOwnThenable(promise, thenable) { 298 | if (thenable._state === FULFILLED) { 299 | fulfill(promise, thenable._result); 300 | } else if (thenable._state === REJECTED) { 301 | thenable._onerror = null; 302 | _reject(promise, thenable._result); 303 | } else { 304 | subscribe(thenable, undefined, function (value) { 305 | return _resolve(promise, value); 306 | }, function (reason) { 307 | return _reject(promise, reason); 308 | }); 309 | } 310 | } 311 | 312 | function handleMaybeThenable(promise, maybeThenable, then$$) { 313 | if (maybeThenable.constructor === promise.constructor && then$$ === then && maybeThenable.constructor.resolve === resolve) { 314 | handleOwnThenable(promise, maybeThenable); 315 | } else { 316 | if (then$$ === GET_THEN_ERROR) { 317 | _reject(promise, GET_THEN_ERROR.error); 318 | } else if (then$$ === undefined) { 319 | fulfill(promise, maybeThenable); 320 | } else if (isFunction(then$$)) { 321 | handleForeignThenable(promise, maybeThenable, then$$); 322 | } else { 323 | fulfill(promise, maybeThenable); 324 | } 325 | } 326 | } 327 | 328 | function _resolve(promise, value) { 329 | if (promise === value) { 330 | _reject(promise, selfFulfillment()); 331 | } else if (objectOrFunction(value)) { 332 | handleMaybeThenable(promise, value, getThen(value)); 333 | } else { 334 | fulfill(promise, value); 335 | } 336 | } 337 | 338 | function publishRejection(promise) { 339 | if (promise._onerror) { 340 | promise._onerror(promise._result); 341 | } 342 | 343 | publish(promise); 344 | } 345 | 346 | function fulfill(promise, value) { 347 | if (promise._state !== PENDING) { 348 | return; 349 | } 350 | 351 | promise._result = value; 352 | promise._state = FULFILLED; 353 | 354 | if (promise._subscribers.length !== 0) { 355 | asap(publish, promise); 356 | } 357 | } 358 | 359 | function _reject(promise, reason) { 360 | if (promise._state !== PENDING) { 361 | return; 362 | } 363 | promise._state = REJECTED; 364 | promise._result = reason; 365 | 366 | asap(publishRejection, promise); 367 | } 368 | 369 | function subscribe(parent, child, onFulfillment, onRejection) { 370 | var _subscribers = parent._subscribers; 371 | var length = _subscribers.length; 372 | 373 | parent._onerror = null; 374 | 375 | _subscribers[length] = child; 376 | _subscribers[length + FULFILLED] = onFulfillment; 377 | _subscribers[length + REJECTED] = onRejection; 378 | 379 | if (length === 0 && parent._state) { 380 | asap(publish, parent); 381 | } 382 | } 383 | 384 | function publish(promise) { 385 | var subscribers = promise._subscribers; 386 | var settled = promise._state; 387 | 388 | if (subscribers.length === 0) { 389 | return; 390 | } 391 | 392 | var child = undefined, 393 | callback = undefined, 394 | detail = promise._result; 395 | 396 | for (var i = 0; i < subscribers.length; i += 3) { 397 | child = subscribers[i]; 398 | callback = subscribers[i + settled]; 399 | 400 | if (child) { 401 | invokeCallback(settled, child, callback, detail); 402 | } else { 403 | callback(detail); 404 | } 405 | } 406 | 407 | promise._subscribers.length = 0; 408 | } 409 | 410 | function ErrorObject() { 411 | this.error = null; 412 | } 413 | 414 | var TRY_CATCH_ERROR = new ErrorObject(); 415 | 416 | function tryCatch(callback, detail) { 417 | try { 418 | return callback(detail); 419 | } catch (e) { 420 | TRY_CATCH_ERROR.error = e; 421 | return TRY_CATCH_ERROR; 422 | } 423 | } 424 | 425 | function invokeCallback(settled, promise, callback, detail) { 426 | var hasCallback = isFunction(callback), 427 | value = undefined, 428 | error = undefined, 429 | succeeded = undefined, 430 | failed = undefined; 431 | 432 | if (hasCallback) { 433 | value = tryCatch(callback, detail); 434 | 435 | if (value === TRY_CATCH_ERROR) { 436 | failed = true; 437 | error = value.error; 438 | value = null; 439 | } else { 440 | succeeded = true; 441 | } 442 | 443 | if (promise === value) { 444 | _reject(promise, cannotReturnOwn()); 445 | return; 446 | } 447 | } else { 448 | value = detail; 449 | succeeded = true; 450 | } 451 | 452 | if (promise._state !== PENDING) { 453 | // noop 454 | } else if (hasCallback && succeeded) { 455 | _resolve(promise, value); 456 | } else if (failed) { 457 | _reject(promise, error); 458 | } else if (settled === FULFILLED) { 459 | fulfill(promise, value); 460 | } else if (settled === REJECTED) { 461 | _reject(promise, value); 462 | } 463 | } 464 | 465 | function initializePromise(promise, resolver) { 466 | try { 467 | resolver(function resolvePromise(value) { 468 | _resolve(promise, value); 469 | }, function rejectPromise(reason) { 470 | _reject(promise, reason); 471 | }); 472 | } catch (e) { 473 | _reject(promise, e); 474 | } 475 | } 476 | 477 | var id = 0; 478 | function nextId() { 479 | return id++; 480 | } 481 | 482 | function makePromise(promise) { 483 | promise[PROMISE_ID] = id++; 484 | promise._state = undefined; 485 | promise._result = undefined; 486 | promise._subscribers = []; 487 | } 488 | 489 | function Enumerator(Constructor, input) { 490 | this._instanceConstructor = Constructor; 491 | this.promise = new Constructor(noop); 492 | 493 | if (!this.promise[PROMISE_ID]) { 494 | makePromise(this.promise); 495 | } 496 | 497 | if (isArray(input)) { 498 | this._input = input; 499 | this.length = input.length; 500 | this._remaining = input.length; 501 | 502 | this._result = new Array(this.length); 503 | 504 | if (this.length === 0) { 505 | fulfill(this.promise, this._result); 506 | } else { 507 | this.length = this.length || 0; 508 | this._enumerate(); 509 | if (this._remaining === 0) { 510 | fulfill(this.promise, this._result); 511 | } 512 | } 513 | } else { 514 | _reject(this.promise, validationError()); 515 | } 516 | } 517 | 518 | function validationError() { 519 | return new Error('Array Methods must be provided an Array'); 520 | }; 521 | 522 | Enumerator.prototype._enumerate = function () { 523 | var length = this.length; 524 | var _input = this._input; 525 | 526 | for (var i = 0; this._state === PENDING && i < length; i++) { 527 | this._eachEntry(_input[i], i); 528 | } 529 | }; 530 | 531 | Enumerator.prototype._eachEntry = function (entry, i) { 532 | var c = this._instanceConstructor; 533 | var resolve$$ = c.resolve; 534 | 535 | if (resolve$$ === resolve) { 536 | var _then = getThen(entry); 537 | 538 | if (_then === then && entry._state !== PENDING) { 539 | entry._onerror = null; 540 | this._settledAt(entry._state, i, entry._result); 541 | } else if (typeof _then !== 'function') { 542 | this._remaining--; 543 | this._result[i] = entry; 544 | } else if (c === Promise) { 545 | var promise = new c(noop); 546 | handleMaybeThenable(promise, entry, _then); 547 | this._willSettleAt(promise, i); 548 | } else { 549 | this._willSettleAt(new c(function (resolve$$) { 550 | return resolve$$(entry); 551 | }), i); 552 | } 553 | } else { 554 | this._willSettleAt(resolve$$(entry), i); 555 | } 556 | }; 557 | 558 | Enumerator.prototype._settledAt = function (state, i, value) { 559 | var promise = this.promise; 560 | 561 | if (promise._state === PENDING) { 562 | this._remaining--; 563 | 564 | if (state === REJECTED) { 565 | _reject(promise, value); 566 | } else { 567 | this._result[i] = value; 568 | } 569 | } 570 | 571 | if (this._remaining === 0) { 572 | fulfill(promise, this._result); 573 | } 574 | }; 575 | 576 | Enumerator.prototype._willSettleAt = function (promise, i) { 577 | var enumerator = this; 578 | 579 | subscribe(promise, undefined, function (value) { 580 | return enumerator._settledAt(FULFILLED, i, value); 581 | }, function (reason) { 582 | return enumerator._settledAt(REJECTED, i, reason); 583 | }); 584 | }; 585 | 586 | /** 587 | `Promise.all` accepts an array of promises, and returns a new promise which 588 | is fulfilled with an array of fulfillment values for the passed promises, or 589 | rejected with the reason of the first passed promise to be rejected. It casts all 590 | elements of the passed iterable to promises as it runs this algorithm. 591 | 592 | Example: 593 | 594 | ```javascript 595 | let promise1 = resolve(1); 596 | let promise2 = resolve(2); 597 | let promise3 = resolve(3); 598 | let promises = [ promise1, promise2, promise3 ]; 599 | 600 | Promise.all(promises).then(function(array){ 601 | // The array here would be [ 1, 2, 3 ]; 602 | }); 603 | ``` 604 | 605 | If any of the `promises` given to `all` are rejected, the first promise 606 | that is rejected will be given as an argument to the returned promises's 607 | rejection handler. For example: 608 | 609 | Example: 610 | 611 | ```javascript 612 | let promise1 = resolve(1); 613 | let promise2 = reject(new Error("2")); 614 | let promise3 = reject(new Error("3")); 615 | let promises = [ promise1, promise2, promise3 ]; 616 | 617 | Promise.all(promises).then(function(array){ 618 | // Code here never runs because there are rejected promises! 619 | }, function(error) { 620 | // error.message === "2" 621 | }); 622 | ``` 623 | 624 | @method all 625 | @static 626 | @param {Array} entries array of promises 627 | @param {String} label optional string for labeling the promise. 628 | Useful for tooling. 629 | @return {Promise} promise that is fulfilled when all `promises` have been 630 | fulfilled, or rejected if any of them become rejected. 631 | @static 632 | */ 633 | function all(entries) { 634 | return new Enumerator(this, entries).promise; 635 | } 636 | 637 | /** 638 | `Promise.race` returns a new promise which is settled in the same way as the 639 | first passed promise to settle. 640 | 641 | Example: 642 | 643 | ```javascript 644 | let promise1 = new Promise(function(resolve, reject){ 645 | setTimeout(function(){ 646 | resolve('promise 1'); 647 | }, 200); 648 | }); 649 | 650 | let promise2 = new Promise(function(resolve, reject){ 651 | setTimeout(function(){ 652 | resolve('promise 2'); 653 | }, 100); 654 | }); 655 | 656 | Promise.race([promise1, promise2]).then(function(result){ 657 | // result === 'promise 2' because it was resolved before promise1 658 | // was resolved. 659 | }); 660 | ``` 661 | 662 | `Promise.race` is deterministic in that only the state of the first 663 | settled promise matters. For example, even if other promises given to the 664 | `promises` array argument are resolved, but the first settled promise has 665 | become rejected before the other promises became fulfilled, the returned 666 | promise will become rejected: 667 | 668 | ```javascript 669 | let promise1 = new Promise(function(resolve, reject){ 670 | setTimeout(function(){ 671 | resolve('promise 1'); 672 | }, 200); 673 | }); 674 | 675 | let promise2 = new Promise(function(resolve, reject){ 676 | setTimeout(function(){ 677 | reject(new Error('promise 2')); 678 | }, 100); 679 | }); 680 | 681 | Promise.race([promise1, promise2]).then(function(result){ 682 | // Code here never runs 683 | }, function(reason){ 684 | // reason.message === 'promise 2' because promise 2 became rejected before 685 | // promise 1 became fulfilled 686 | }); 687 | ``` 688 | 689 | An example real-world use case is implementing timeouts: 690 | 691 | ```javascript 692 | Promise.race([ajax('foo.json'), timeout(5000)]) 693 | ``` 694 | 695 | @method race 696 | @static 697 | @param {Array} promises array of promises to observe 698 | Useful for tooling. 699 | @return {Promise} a promise which settles in the same way as the first passed 700 | promise to settle. 701 | */ 702 | function race(entries) { 703 | /*jshint validthis:true */ 704 | var Constructor = this; 705 | 706 | if (!isArray(entries)) { 707 | return new Constructor(function (_, reject) { 708 | return reject(new TypeError('You must pass an array to race.')); 709 | }); 710 | } else { 711 | return new Constructor(function (resolve, reject) { 712 | var length = entries.length; 713 | for (var i = 0; i < length; i++) { 714 | Constructor.resolve(entries[i]).then(resolve, reject); 715 | } 716 | }); 717 | } 718 | } 719 | 720 | /** 721 | `Promise.reject` returns a promise rejected with the passed `reason`. 722 | It is shorthand for the following: 723 | 724 | ```javascript 725 | let promise = new Promise(function(resolve, reject){ 726 | reject(new Error('WHOOPS')); 727 | }); 728 | 729 | promise.then(function(value){ 730 | // Code here doesn't run because the promise is rejected! 731 | }, function(reason){ 732 | // reason.message === 'WHOOPS' 733 | }); 734 | ``` 735 | 736 | Instead of writing the above, your code now simply becomes the following: 737 | 738 | ```javascript 739 | let promise = Promise.reject(new Error('WHOOPS')); 740 | 741 | promise.then(function(value){ 742 | // Code here doesn't run because the promise is rejected! 743 | }, function(reason){ 744 | // reason.message === 'WHOOPS' 745 | }); 746 | ``` 747 | 748 | @method reject 749 | @static 750 | @param {Any} reason value that the returned promise will be rejected with. 751 | Useful for tooling. 752 | @return {Promise} a promise rejected with the given `reason`. 753 | */ 754 | function reject(reason) { 755 | /*jshint validthis:true */ 756 | var Constructor = this; 757 | var promise = new Constructor(noop); 758 | _reject(promise, reason); 759 | return promise; 760 | } 761 | 762 | function needsResolver() { 763 | throw new TypeError('You must pass a resolver function as the first argument to the promise constructor'); 764 | } 765 | 766 | function needsNew() { 767 | throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); 768 | } 769 | 770 | /** 771 | Promise objects represent the eventual result of an asynchronous operation. The 772 | primary way of interacting with a promise is through its `then` method, which 773 | registers callbacks to receive either a promise's eventual value or the reason 774 | why the promise cannot be fulfilled. 775 | 776 | Terminology 777 | ----------- 778 | 779 | - `promise` is an object or function with a `then` method whose behavior conforms to this specification. 780 | - `thenable` is an object or function that defines a `then` method. 781 | - `value` is any legal JavaScript value (including undefined, a thenable, or a promise). 782 | - `exception` is a value that is thrown using the throw statement. 783 | - `reason` is a value that indicates why a promise was rejected. 784 | - `settled` the final resting state of a promise, fulfilled or rejected. 785 | 786 | A promise can be in one of three states: pending, fulfilled, or rejected. 787 | 788 | Promises that are fulfilled have a fulfillment value and are in the fulfilled 789 | state. Promises that are rejected have a rejection reason and are in the 790 | rejected state. A fulfillment value is never a thenable. 791 | 792 | Promises can also be said to *resolve* a value. If this value is also a 793 | promise, then the original promise's settled state will match the value's 794 | settled state. So a promise that *resolves* a promise that rejects will 795 | itself reject, and a promise that *resolves* a promise that fulfills will 796 | itself fulfill. 797 | 798 | 799 | Basic Usage: 800 | ------------ 801 | 802 | ```js 803 | let promise = new Promise(function(resolve, reject) { 804 | // on success 805 | resolve(value); 806 | 807 | // on failure 808 | reject(reason); 809 | }); 810 | 811 | promise.then(function(value) { 812 | // on fulfillment 813 | }, function(reason) { 814 | // on rejection 815 | }); 816 | ``` 817 | 818 | Advanced Usage: 819 | --------------- 820 | 821 | Promises shine when abstracting away asynchronous interactions such as 822 | `XMLHttpRequest`s. 823 | 824 | ```js 825 | function getJSON(url) { 826 | return new Promise(function(resolve, reject){ 827 | let xhr = new XMLHttpRequest(); 828 | 829 | xhr.open('GET', url); 830 | xhr.onreadystatechange = handler; 831 | xhr.responseType = 'json'; 832 | xhr.setRequestHeader('Accept', 'application/json'); 833 | xhr.send(); 834 | 835 | function handler() { 836 | if (this.readyState === this.DONE) { 837 | if (this.status === 200) { 838 | resolve(this.response); 839 | } else { 840 | reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']')); 841 | } 842 | } 843 | }; 844 | }); 845 | } 846 | 847 | getJSON('/posts.json').then(function(json) { 848 | // on fulfillment 849 | }, function(reason) { 850 | // on rejection 851 | }); 852 | ``` 853 | 854 | Unlike callbacks, promises are great composable primitives. 855 | 856 | ```js 857 | Promise.all([ 858 | getJSON('/posts'), 859 | getJSON('/comments') 860 | ]).then(function(values){ 861 | values[0] // => postsJSON 862 | values[1] // => commentsJSON 863 | 864 | return values; 865 | }); 866 | ``` 867 | 868 | @class Promise 869 | @param {function} resolver 870 | Useful for tooling. 871 | @constructor 872 | */ 873 | function Promise(resolver) { 874 | this[PROMISE_ID] = nextId(); 875 | this._result = this._state = undefined; 876 | this._subscribers = []; 877 | 878 | if (noop !== resolver) { 879 | typeof resolver !== 'function' && needsResolver(); 880 | this instanceof Promise ? initializePromise(this, resolver) : needsNew(); 881 | } 882 | } 883 | 884 | Promise.all = all; 885 | Promise.race = race; 886 | Promise.resolve = resolve; 887 | Promise.reject = reject; 888 | Promise._setScheduler = setScheduler; 889 | Promise._setAsap = setAsap; 890 | Promise._asap = asap; 891 | 892 | Promise.prototype = { 893 | constructor: Promise, 894 | 895 | /** 896 | The primary way of interacting with a promise is through its `then` method, 897 | which registers callbacks to receive either a promise's eventual value or the 898 | reason why the promise cannot be fulfilled. 899 | 900 | ```js 901 | findUser().then(function(user){ 902 | // user is available 903 | }, function(reason){ 904 | // user is unavailable, and you are given the reason why 905 | }); 906 | ``` 907 | 908 | Chaining 909 | -------- 910 | 911 | The return value of `then` is itself a promise. This second, 'downstream' 912 | promise is resolved with the return value of the first promise's fulfillment 913 | or rejection handler, or rejected if the handler throws an exception. 914 | 915 | ```js 916 | findUser().then(function (user) { 917 | return user.name; 918 | }, function (reason) { 919 | return 'default name'; 920 | }).then(function (userName) { 921 | // If `findUser` fulfilled, `userName` will be the user's name, otherwise it 922 | // will be `'default name'` 923 | }); 924 | 925 | findUser().then(function (user) { 926 | throw new Error('Found user, but still unhappy'); 927 | }, function (reason) { 928 | throw new Error('`findUser` rejected and we're unhappy'); 929 | }).then(function (value) { 930 | // never reached 931 | }, function (reason) { 932 | // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. 933 | // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. 934 | }); 935 | ``` 936 | If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. 937 | 938 | ```js 939 | findUser().then(function (user) { 940 | throw new PedagogicalException('Upstream error'); 941 | }).then(function (value) { 942 | // never reached 943 | }).then(function (value) { 944 | // never reached 945 | }, function (reason) { 946 | // The `PedgagocialException` is propagated all the way down to here 947 | }); 948 | ``` 949 | 950 | Assimilation 951 | ------------ 952 | 953 | Sometimes the value you want to propagate to a downstream promise can only be 954 | retrieved asynchronously. This can be achieved by returning a promise in the 955 | fulfillment or rejection handler. The downstream promise will then be pending 956 | until the returned promise is settled. This is called *assimilation*. 957 | 958 | ```js 959 | findUser().then(function (user) { 960 | return findCommentsByAuthor(user); 961 | }).then(function (comments) { 962 | // The user's comments are now available 963 | }); 964 | ``` 965 | 966 | If the assimliated promise rejects, then the downstream promise will also reject. 967 | 968 | ```js 969 | findUser().then(function (user) { 970 | return findCommentsByAuthor(user); 971 | }).then(function (comments) { 972 | // If `findCommentsByAuthor` fulfills, we'll have the value here 973 | }, function (reason) { 974 | // If `findCommentsByAuthor` rejects, we'll have the reason here 975 | }); 976 | ``` 977 | 978 | Simple Example 979 | -------------- 980 | 981 | Synchronous Example 982 | 983 | ```javascript 984 | let result; 985 | 986 | try { 987 | result = findResult(); 988 | // success 989 | } catch(reason) { 990 | // failure 991 | } 992 | ``` 993 | 994 | Errback Example 995 | 996 | ```js 997 | findResult(function(result, err){ 998 | if (err) { 999 | // failure 1000 | } else { 1001 | // success 1002 | } 1003 | }); 1004 | ``` 1005 | 1006 | Promise Example; 1007 | 1008 | ```javascript 1009 | findResult().then(function(result){ 1010 | // success 1011 | }, function(reason){ 1012 | // failure 1013 | }); 1014 | ``` 1015 | 1016 | Advanced Example 1017 | -------------- 1018 | 1019 | Synchronous Example 1020 | 1021 | ```javascript 1022 | let author, books; 1023 | 1024 | try { 1025 | author = findAuthor(); 1026 | books = findBooksByAuthor(author); 1027 | // success 1028 | } catch(reason) { 1029 | // failure 1030 | } 1031 | ``` 1032 | 1033 | Errback Example 1034 | 1035 | ```js 1036 | 1037 | function foundBooks(books) { 1038 | 1039 | } 1040 | 1041 | function failure(reason) { 1042 | 1043 | } 1044 | 1045 | findAuthor(function(author, err){ 1046 | if (err) { 1047 | failure(err); 1048 | // failure 1049 | } else { 1050 | try { 1051 | findBoooksByAuthor(author, function(books, err) { 1052 | if (err) { 1053 | failure(err); 1054 | } else { 1055 | try { 1056 | foundBooks(books); 1057 | } catch(reason) { 1058 | failure(reason); 1059 | } 1060 | } 1061 | }); 1062 | } catch(error) { 1063 | failure(err); 1064 | } 1065 | // success 1066 | } 1067 | }); 1068 | ``` 1069 | 1070 | Promise Example; 1071 | 1072 | ```javascript 1073 | findAuthor(). 1074 | then(findBooksByAuthor). 1075 | then(function(books){ 1076 | // found books 1077 | }).catch(function(reason){ 1078 | // something went wrong 1079 | }); 1080 | ``` 1081 | 1082 | @method then 1083 | @param {Function} onFulfilled 1084 | @param {Function} onRejected 1085 | Useful for tooling. 1086 | @return {Promise} 1087 | */ 1088 | then: then, 1089 | 1090 | /** 1091 | `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same 1092 | as the catch block of a try/catch statement. 1093 | 1094 | ```js 1095 | function findAuthor(){ 1096 | throw new Error('couldn't find that author'); 1097 | } 1098 | 1099 | // synchronous 1100 | try { 1101 | findAuthor(); 1102 | } catch(reason) { 1103 | // something went wrong 1104 | } 1105 | 1106 | // async with promises 1107 | findAuthor().catch(function(reason){ 1108 | // something went wrong 1109 | }); 1110 | ``` 1111 | 1112 | @method catch 1113 | @param {Function} onRejection 1114 | Useful for tooling. 1115 | @return {Promise} 1116 | */ 1117 | 'catch': function _catch(onRejection) { 1118 | return this.then(null, onRejection); 1119 | }, 1120 | 1121 | /** 1122 | `finally` will be invoked regardless of the promise's fate just as native 1123 | try/catch/finally behaves 1124 | 1125 | Synchronous example: 1126 | 1127 | ```js 1128 | findAuthor() { 1129 | if (Math.random() > 0.5) { 1130 | throw new Error(); 1131 | } 1132 | return new Author(); 1133 | } 1134 | 1135 | try { 1136 | return findAuthor(); // succeed or fail 1137 | } catch(error) { 1138 | return findOtherAuthor(); 1139 | } finally { 1140 | // always runs 1141 | // doesn't affect the return value 1142 | } 1143 | ``` 1144 | 1145 | Asynchronous example: 1146 | 1147 | ```js 1148 | findAuthor().catch(function(reason){ 1149 | return findOtherAuthor(); 1150 | }).finally(function(){ 1151 | // author was either found, or not 1152 | }); 1153 | ``` 1154 | 1155 | @method finally 1156 | @param {Function} callback 1157 | @param {String} label optional string for labeling the promise. 1158 | Useful for tooling. 1159 | @return {Promise} 1160 | */ 1161 | 'finally': function _finally(callback, label) { 1162 | var promise = this; 1163 | var constructor = promise.constructor; 1164 | 1165 | return promise.then(function (value) { 1166 | return constructor.resolve(callback()).then(function () { 1167 | return value; 1168 | }); 1169 | }, function (reason) { 1170 | return constructor.resolve(callback()).then(function () { 1171 | throw reason; 1172 | }); 1173 | }); 1174 | }, 1175 | 1176 | // Ported from RSVP.js 1177 | _onerror: function _onerror(reason) { 1178 | var promise = this; 1179 | setTimeout(function () { 1180 | if (promise._onerror && typeof Promise.onerror === 'function') { 1181 | Promise.onerror(reason); 1182 | } 1183 | }, 0); 1184 | } 1185 | }; 1186 | 1187 | function polyfill() { 1188 | var local = undefined; 1189 | 1190 | if (typeof global !== 'undefined') { 1191 | local = global; 1192 | } else if (typeof self !== 'undefined') { 1193 | local = self; 1194 | } else { 1195 | try { 1196 | local = Function('return this')(); 1197 | } catch (e) { 1198 | throw new Error('polyfill failed because global object is unavailable in this environment'); 1199 | } 1200 | } 1201 | 1202 | var P = local.Promise; 1203 | 1204 | if (P) { 1205 | var promiseToString = null; 1206 | try { 1207 | promiseToString = Object.prototype.toString.call(P.resolve()); 1208 | } catch (e) { 1209 | // silently ignored 1210 | } 1211 | 1212 | if (promiseToString === '[object Promise]' && !P.cast) { 1213 | return; 1214 | } 1215 | } 1216 | 1217 | local.Promise = Promise; 1218 | } 1219 | 1220 | // Strange compat.. 1221 | Promise.polyfill = polyfill; 1222 | Promise.Promise = Promise; 1223 | 1224 | return Promise; 1225 | 1226 | }))); 1227 | //# sourceMappingURL=es6-promise.map 1228 | --------------------------------------------------------------------------------