Skip to content

Commit

Permalink
use NewPromiseCapability logic in Promise.try
Browse files Browse the repository at this point in the history
  • Loading branch information
zloirock committed Jul 16, 2017
1 parent 65c0fc5 commit db0d4a5
Show file tree
Hide file tree
Showing 17 changed files with 1,171 additions and 1,052 deletions.
681 changes: 355 additions & 326 deletions client/core.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions client/core.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/core.min.js.map

Large diffs are not rendered by default.

657 changes: 343 additions & 314 deletions client/library.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions client/library.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/library.min.js.map

Large diffs are not rendered by default.

681 changes: 355 additions & 326 deletions client/shim.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions client/shim.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/shim.min.js.map

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions library/modules/_new-promise-capability.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';
// 25.4.1.5 NewPromiseCapability(C)
var aFunction = require('./_a-function');

function PromiseCapability(C) {
var resolve, reject;
this.promise = new C(function ($$resolve, $$reject) {
if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');
resolve = $$resolve;
reject = $$reject;
});
this.resolve = aFunction(resolve);
this.reject = aFunction(reject);
}

module.exports.f = function (C) {
return new PromiseCapability(C);
};
7 changes: 7 additions & 0 deletions library/modules/_perform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = function (exec) {
try {
return { e: false, v: exec() };
} catch (e) {
return { e: true, v: e };
}
};
55 changes: 22 additions & 33 deletions library/modules/es6.promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ var forOf = require('./_for-of');
var speciesConstructor = require('./_species-constructor');
var task = require('./_task').set;
var microtask = require('./_microtask')();
var newPromiseCapabilityModule = require('./_new-promise-capability');
var perform = require('./_perform');
var PROMISE = 'Promise';
var TypeError = global.TypeError;
var process = global.process;
var $Promise = global[PROMISE];
var isNode = classof(process) == 'process';
var empty = function () { /* empty */ };
var Internal, GenericPromiseCapability, Wrapper;
var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper;
var newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f;

var USE_NATIVE = !!function () {
try {
Expand All @@ -32,36 +35,16 @@ var USE_NATIVE = !!function () {
}();

// helpers
var sameConstructor = function (a, b) {
var sameConstructor = LIBRARY ? function (a, b) {
// with library wrapper special case
return a === b || a === $Promise && b === Wrapper;
} : function (a, b) {
return a === b;
};
var isThenable = function (it) {
var then;
return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
};
var newPromiseCapability = function (C) {
return sameConstructor($Promise, C)
? new PromiseCapability(C)
: new GenericPromiseCapability(C);
};
var PromiseCapability = GenericPromiseCapability = function (C) {
var resolve, reject;
this.promise = new C(function ($$resolve, $$reject) {
if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');
resolve = $$resolve;
reject = $$reject;
});
this.resolve = aFunction(resolve);
this.reject = aFunction(reject);
};
var perform = function (exec) {
try {
exec();
} catch (e) {
return { error: e };
}
};
var notify = function (promise, isReject) {
if (promise._n) return;
promise._n = true;
Expand Down Expand Up @@ -107,9 +90,10 @@ var notify = function (promise, isReject) {
var onUnhandled = function (promise) {
task.call(global, function () {
var value = promise._v;
var abrupt, handler, console;
if (isUnhandled(promise)) {
abrupt = perform(function () {
var unhandled = isUnhandled(promise);
var result, handler, console;
if (unhandled) {
result = perform(function () {
if (isNode) {
process.emit('unhandledRejection', value, promise);
} else if (handler = global.onunhandledrejection) {
Expand All @@ -121,7 +105,7 @@ var onUnhandled = function (promise) {
// Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
promise._h = isNode || isUnhandled(promise) ? 2 : 1;
} promise._a = undefined;
if (abrupt) throw abrupt.error;
if (unhandled && result.e) throw result.v;
});
};
var isUnhandled = function (promise) {
Expand Down Expand Up @@ -221,12 +205,17 @@ if (!USE_NATIVE) {
return this.then(undefined, onRejected);
}
});
PromiseCapability = function () {
OwnPromiseCapability = function () {
var promise = new Internal();
this.promise = promise;
this.resolve = ctx($resolve, promise, 1);
this.reject = ctx($reject, promise, 1);
};
newPromiseCapabilityModule.f = newPromiseCapability = function (C) {
return sameConstructor($Promise, C)
? new OwnPromiseCapability(C)
: newGenericPromiseCapability(C);
};
}

$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise });
Expand Down Expand Up @@ -264,7 +253,7 @@ $export($export.S + $export.F * !(USE_NATIVE && require('./_iter-detect')(functi
var capability = newPromiseCapability(C);
var resolve = capability.resolve;
var reject = capability.reject;
var abrupt = perform(function () {
var result = perform(function () {
var values = [];
var index = 0;
var remaining = 1;
Expand All @@ -282,20 +271,20 @@ $export($export.S + $export.F * !(USE_NATIVE && require('./_iter-detect')(functi
});
--remaining || resolve(values);
});
if (abrupt) reject(abrupt.error);
if (result.e) reject(result.v);
return capability.promise;
},
// 25.4.4.4 Promise.race(iterable)
race: function race(iterable) {
var C = this;
var capability = newPromiseCapability(C);
var reject = capability.reject;
var abrupt = perform(function () {
var result = perform(function () {
forOf(iterable, false, function (promise) {
C.resolve(promise).then(capability.resolve, reject);
});
});
if (abrupt) reject(abrupt.error);
if (result.e) reject(result.v);
return capability.promise;
}
});
10 changes: 6 additions & 4 deletions library/modules/es7.promise.try.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use strict';
// https:/tc39/proposal-promise-try
var $export = require('./_export');
var newPromiseCapability = require('./_new-promise-capability');
var perform = require('./_perform');

$export($export.S, 'Promise', { 'try': function (callbackfn) {
// TODO: use NewPromiseCapability logic
return new this(function (resolve) {
resolve(callbackfn());
});
var promiseCapability = newPromiseCapability.f(this);
var result = perform(callbackfn);
(result.e ? promiseCapability.reject : promiseCapability.resolve)(result.v);
return promiseCapability.promise;
} });
18 changes: 18 additions & 0 deletions modules/_new-promise-capability.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';
// 25.4.1.5 NewPromiseCapability(C)
var aFunction = require('./_a-function');

function PromiseCapability(C) {
var resolve, reject;
this.promise = new C(function ($$resolve, $$reject) {
if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');
resolve = $$resolve;
reject = $$reject;
});
this.resolve = aFunction(resolve);
this.reject = aFunction(reject);
}

module.exports.f = function (C) {
return new PromiseCapability(C);
};
7 changes: 7 additions & 0 deletions modules/_perform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = function (exec) {
try {
return { e: false, v: exec() };
} catch (e) {
return { e: true, v: e };
}
};
55 changes: 22 additions & 33 deletions modules/es6.promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ var forOf = require('./_for-of');
var speciesConstructor = require('./_species-constructor');
var task = require('./_task').set;
var microtask = require('./_microtask')();
var newPromiseCapabilityModule = require('./_new-promise-capability');
var perform = require('./_perform');
var PROMISE = 'Promise';
var TypeError = global.TypeError;
var process = global.process;
var $Promise = global[PROMISE];
var isNode = classof(process) == 'process';
var empty = function () { /* empty */ };
var Internal, GenericPromiseCapability, Wrapper;
var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper;
var newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f;

var USE_NATIVE = !!function () {
try {
Expand All @@ -32,36 +35,16 @@ var USE_NATIVE = !!function () {
}();

// helpers
var sameConstructor = function (a, b) {
var sameConstructor = LIBRARY ? function (a, b) {
// with library wrapper special case
return a === b || a === $Promise && b === Wrapper;
} : function (a, b) {
return a === b;
};
var isThenable = function (it) {
var then;
return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
};
var newPromiseCapability = function (C) {
return sameConstructor($Promise, C)
? new PromiseCapability(C)
: new GenericPromiseCapability(C);
};
var PromiseCapability = GenericPromiseCapability = function (C) {
var resolve, reject;
this.promise = new C(function ($$resolve, $$reject) {
if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');
resolve = $$resolve;
reject = $$reject;
});
this.resolve = aFunction(resolve);
this.reject = aFunction(reject);
};
var perform = function (exec) {
try {
exec();
} catch (e) {
return { error: e };
}
};
var notify = function (promise, isReject) {
if (promise._n) return;
promise._n = true;
Expand Down Expand Up @@ -107,9 +90,10 @@ var notify = function (promise, isReject) {
var onUnhandled = function (promise) {
task.call(global, function () {
var value = promise._v;
var abrupt, handler, console;
if (isUnhandled(promise)) {
abrupt = perform(function () {
var unhandled = isUnhandled(promise);
var result, handler, console;
if (unhandled) {
result = perform(function () {
if (isNode) {
process.emit('unhandledRejection', value, promise);
} else if (handler = global.onunhandledrejection) {
Expand All @@ -121,7 +105,7 @@ var onUnhandled = function (promise) {
// Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
promise._h = isNode || isUnhandled(promise) ? 2 : 1;
} promise._a = undefined;
if (abrupt) throw abrupt.error;
if (unhandled && result.e) throw result.v;
});
};
var isUnhandled = function (promise) {
Expand Down Expand Up @@ -221,12 +205,17 @@ if (!USE_NATIVE) {
return this.then(undefined, onRejected);
}
});
PromiseCapability = function () {
OwnPromiseCapability = function () {
var promise = new Internal();
this.promise = promise;
this.resolve = ctx($resolve, promise, 1);
this.reject = ctx($reject, promise, 1);
};
newPromiseCapabilityModule.f = newPromiseCapability = function (C) {
return sameConstructor($Promise, C)
? new OwnPromiseCapability(C)
: newGenericPromiseCapability(C);
};
}

$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise });
Expand Down Expand Up @@ -264,7 +253,7 @@ $export($export.S + $export.F * !(USE_NATIVE && require('./_iter-detect')(functi
var capability = newPromiseCapability(C);
var resolve = capability.resolve;
var reject = capability.reject;
var abrupt = perform(function () {
var result = perform(function () {
var values = [];
var index = 0;
var remaining = 1;
Expand All @@ -282,20 +271,20 @@ $export($export.S + $export.F * !(USE_NATIVE && require('./_iter-detect')(functi
});
--remaining || resolve(values);
});
if (abrupt) reject(abrupt.error);
if (result.e) reject(result.v);
return capability.promise;
},
// 25.4.4.4 Promise.race(iterable)
race: function race(iterable) {
var C = this;
var capability = newPromiseCapability(C);
var reject = capability.reject;
var abrupt = perform(function () {
var result = perform(function () {
forOf(iterable, false, function (promise) {
C.resolve(promise).then(capability.resolve, reject);
});
});
if (abrupt) reject(abrupt.error);
if (result.e) reject(result.v);
return capability.promise;
}
});
10 changes: 6 additions & 4 deletions modules/es7.promise.try.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use strict';
// https:/tc39/proposal-promise-try
var $export = require('./_export');
var newPromiseCapability = require('./_new-promise-capability');
var perform = require('./_perform');

$export($export.S, 'Promise', { 'try': function (callbackfn) {
// TODO: use NewPromiseCapability logic
return new this(function (resolve) {
resolve(callbackfn());
});
var promiseCapability = newPromiseCapability.f(this);
var result = perform(callbackfn);
(result.e ? promiseCapability.reject : promiseCapability.resolve)(result.v);
return promiseCapability.promise;
} });

0 comments on commit db0d4a5

Please sign in to comment.