{"id":13508925,"url":"https://github.com/getify/native-promise-only","last_synced_at":"2026-01-10T03:06:03.448Z","repository":{"id":16685830,"uuid":"19442108","full_name":"getify/native-promise-only","owner":"getify","description":"A polyfill for native ES6 Promises as close as possible (no extensions) to the strict spec definitions.","archived":true,"fork":false,"pushed_at":"2019-10-27T02:11:57.000Z","size":71,"stargazers_count":718,"open_issues_count":0,"forks_count":69,"subscribers_count":32,"default_branch":"master","last_synced_at":"2025-03-13T18:27:57.342Z","etag":null,"topics":["javascript","polyfill","promises"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/getify.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-05-05T02:56:08.000Z","updated_at":"2025-01-09T22:42:13.000Z","dependencies_parsed_at":"2022-09-09T03:23:10.919Z","dependency_job_id":null,"html_url":"https://github.com/getify/native-promise-only","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getify%2Fnative-promise-only","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getify%2Fnative-promise-only/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getify%2Fnative-promise-only/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getify%2Fnative-promise-only/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/getify","download_url":"https://codeload.github.com/getify/native-promise-only/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246314042,"owners_count":20757455,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","polyfill","promises"],"created_at":"2024-08-01T02:01:00.533Z","updated_at":"2026-01-10T03:06:03.406Z","avatar_url":"https://github.com/getify.png","language":"JavaScript","readme":"# Native Promise Only (NPO)\n\n[![CDNJS](https://img.shields.io/cdnjs/v/native-promise-only.svg)](https://cdnjs.com/libraries/native-promise-only/)\n\nA polyfill for native ES6 Promises as close as possible (no extensions) to the strict spec definitions.\n\n## Intent\n\nThe aim of this project is to be the smallest polyfill for Promises, staying as close as possible to what's specified in both [Promises/A+](http://promisesaplus.com) and the [upcoming ES6 specification](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects).\n\nAn equally important goal is to avoid exposing any capability for promise-state to be mutated externally. The [Known Limitations](#known-limitations) section below explains the trade-offs of that balance.\n\n## Usage\n\nTo use this polyfill in the browser, include the \"npo.js\" file (see the instructions in [Tests/Compliance section](#testscompliance) below for how to build \"npo.js\" if you don't have it already) with your site's scripts. It's a polyfill, which means it will not overwrite `Promise` if it exists as a global already, so it's safe to include unconditionally.\n\nTo use with AMD, import the \"npo.js\" file module.\n\nTo install the polyfill via bower, run:\n\n```\nbower install native-promise-only\n```\n\nTo install the polyfill via npm, run:\n\n```\nnpm install native-promise-only\n```\n\nThen require the module into your node code:\n\n```js\nrequire(\"native-promise-only\");\n```\n\nNotice that using the module in this way, we don't assign the module's public API to any variable. **We don't need to**, because it's a polyfill that intentionally patches the global environment (in this case to the `Promise` name) once included.\n\nIf you *want* to also have a reference pointing to the same `Promise` global, you *can also* assign the return value from the `require(..)` statement, but it's strongly recommended that you use the same `Promise` name so as to not create confusion:\n\n```js\nvar Promise = require(\"native-promise-only\");\n\n// Promise === global.Promise; // true!\n```\n\nOther than the below [Known Limitations](#known-limitations) discussion ~~and some browser bugs (such as [these](https://gist.github.com/getify/bd11ccf1eff2efdac0fb)) which **this polyfill doesn't suffer from**~~, your promises should operate the same in all JS environments.\n\nExactly like native promises, here's a quick example of how you create and use the polyfilled promises:\n\n```js\nvar p = new Promise(function(resolve,reject){\n\tsetTimeout(function(){\n\t\tresolve(\"Yay!\");\n\t},100);\n});\n\np.then(function(msg){\n\tconsole.log(msg); // Yay!\n});\n```\n\nFor more on promises, check these blog posts out:\n\n1. Back-story on the hows and whys behind promises (chaining, errors, etc): [multi-part blog post series \"Promises\"](http://blog.getify.com/promises-part-1/) by [getify](http://twitter.com/getify) (me).\n2. Using and enjoying native promises: [JavaScript Promises](http://www.html5rocks.com/en/tutorials/es6/promises/) by [Jake Archibald](http://twitter.com/jaffathecake).\n\n## Known Limitations\n\nA promise object from this polyfill **will be** an instance of the `Promise` constructor, which makes identification of genuine promises easier:\n\n```js\nvar p = new Promise(..);\n\np instanceof Promise; // true\n```\n\nHowever, these promise instances don't inherit (delegate to) a *meaningful* `Promise.prototype` object for their methods (there is one, it's just mostly empty).\n\nConsider:\n\n```js\nvar p = new Promise(..);\n\nObject.getOwnPropertyNames( p ); // [ then, catch ]\nObject.getOwnPropertyNames( Promise.prototype ); // [ constructor ]\n```\n\nAs such, these promises are not really \"sub-classable\" in the ES6 `class` / `extends` sense, though theoretically you should be able to do that in ES6 with the built-in Promises.\n\nTo read a full explanation of why, read [Part 3: The Trust Problem](http://blog.getify.com/promises-part-3/) of my blog post series on Promises.\n\nBriefly, the reason for this deviation is that there's a choice between having delegated methods on the `.prototype` or having private state. Since **the spirit of promises was always to ensure trustability** -- that promises were immutable (from the outside) to everyone except the initial resolver/deferred -- private state is a critically important feature to preserve.\n\nMany other ES6 promise shims/libs seem to have forgotten that important point, as many of them either expose the state publicly on the object instance or provide public accessor methods which can externally mutate a promise's state. Both of these deviations are **intolerable** in my opinion, so this library chose the opposite trade-off: *no ES6 sub-classing*.\n\nAny trade-off is a shame, but this one is the least of a few evils, and probably won't prove to limit very many, as there are only a limited number of use-cases for `extend`ing `Promise` in the ES6 sub-class sense.\n\n## Still Want More?\n\nThis project intentionally adheres pretty strictly to the narrow core of [Promises/A+](http://promisesaplus.com) as adopted/implemented by ES6 into the native `Promise()` mechanism.\n\nBut it's quite likely that you will [experience a variety of scenarios](http://blog.getify.com/promises-part-5/) in which using *only* native promises might be tedious, limiting, or more trouble than it's worth. There's good reason why most other **Promises/A+** \"compliant\" libs are actually superset extensions on the narrow core: **because async flow-control is often quite complex in the real world.**\n\n*Native Promise Only* will **NOT** add any of these extra flourishes. Sorry.\n\n**However, I have another project**: [asynquence](http://github.com/getify/asynquence) (async + sequence). It's an abstraction on top of the promises concept (promises are hidden inside), designed to drastically improve the readability and expressiveness of your async flow-control code.\n\nYou simply express your async flow-control and *asynquence* creates and chains all the promises for you underneath. **Super simple.**\n\n*asynquence* has a custom implementation for the internal \"promises\" it uses, and as such does not need native `Promises`, nor does it need/include this polyfill.\n\nGet your feet wet with native promises first, but then when you go looking for something more, consider [asynquence](http://github.com/getify/asynquence) (which is [vastly more powerful](http://davidwalsh.name/asynquence-part-1) and is still only ~2k!).\n\n## Tests/Compliance\n\n\u003ca href=\"http://promisesaplus.com/\" float=\"right\"\u003e\n    \u003cimg src=\"http://promisesaplus.com/assets/logo-small.png\" alt=\"Promises/A+ logo\"\n         title=\"Promises/A+ 1.1 compliant\" align=\"right\" /\u003e\n\u003c/a\u003e\n\n*Native Promise Only* is \"spec compliant\" in the sense of passing all tests in the [Promises/A+ Test Suite](https://github.com/promises-aplus/promises-tests).\n\nTo run all tests:\n\n1. Either git-clone this repo or run `npm install native-promise-only`, and then switch into that project root.\n2. Run `npm install` in the project root to install the dev-dependencies.\n3. If you didn't get *native-promise-only* from npm, then from the project root, run `./build.js` or `node build.js` or `npm run build` to generate the minified \"npo.js\" in the project root.\n4. Finally, run `npm test`.\n\n**Note:** Other tests need to be added, such as testing the `Promise()` constructor's behavior, as well as the `Promise.*` static helpers (`resolve(..)`, `reject(..)`, `all(..)`, and `race(..)`), none of which are covered by the Promises/A+ test suite.\n\nDeveloping a more comprehensive test-suite to augment the  Promises/A+ test suite **is now another primary goal** of this project.\n\n## License\n\nThe code and all the documentation are released under the MIT license.\n\nhttp://getify.mit-license.org/\n","funding_links":[],"categories":[":mortar_board: 搜罗一切酷酷的东西","JavaScript","Promises/A+ Implementations (ES6/ES2015 compatible)","Packages"],"sub_categories":["Strict Implementations","Control flow"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetify%2Fnative-promise-only","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgetify%2Fnative-promise-only","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetify%2Fnative-promise-only/lists"}