Make m.request work with async/await correctly. (#2428)

* s/xhr/request/g

`m.xhr` was a relic of the rewrite days prior to the release of v1.0.0,
before it was renamed `m.request` to align with v0.2.x. This just strips
some of that legacy naming.

* Make this work with `async`/`await` correctly.

It looked like a V8 bug, but read the two big code comments and follow
their links. It's a bit more subtle than it looks, and V8's in the right
here.
This commit is contained in:
Isiah Meadows 2019-06-10 19:48:04 -04:00 committed by GitHub
parent 8a7eae00ed
commit 0a1a33a036
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 143 additions and 59 deletions

View file

@ -6,6 +6,16 @@ module.exports = function($window, Promise) {
var callbackCount = 0
var oncompletion
function PromiseProxy(executor) {
return new Promise(executor)
}
// In case the global Promise is some userland library's where they rely on
// `foo instanceof this.constructor`, `this.constructor.resolve(value)`, or
// similar. Let's *not* break them.
PromiseProxy.prototype = Promise.prototype
PromiseProxy.__proto__ = Promise // eslint-disable-line no-proto
function makeRequest(factory) {
return function(url, args) {
if (typeof url !== "string") { args = url; url = url.url }
@ -33,6 +43,14 @@ module.exports = function($window, Promise) {
function wrap(promise) {
var then = promise.then
// Set the constructor, so engines know to not await or resolve
// this as a native promise. At the time of writing, this is
// only necessary for V8, but their behavior is the correct
// behavior per spec. See this spec issue for more details:
// https://github.com/tc39/ecma262/issues/1577. Also, see the
// corresponding comment in `request/tests/test-request.js` for
// a bit more background on the issue at hand.
promise.constructor = PromiseProxy
promise.then = function() {
count++
var next = then.apply(promise, arguments)