зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1170760 part 11. Add subclassing support to Promise::Reject. r=baku,efaust
This commit is contained in:
Родитель
93faa5b1b0
Коммит
0bbce93c83
|
@ -273,7 +273,7 @@ var RemoteTabViewer = {
|
|||
}.bind(this);
|
||||
|
||||
return CloudSync().tabs.getRemoteTabs()
|
||||
.then(updateTabList, Promise.reject);
|
||||
.then(updateTabList, Promise.reject.bind(Promise));
|
||||
},
|
||||
|
||||
adjustContextMenu: function (event) {
|
||||
|
|
|
@ -1092,22 +1092,56 @@ Promise::Resolve(nsIGlobalObject* aGlobal, JSContext* aCx,
|
|||
return promise.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<Promise>
|
||||
/* static */ void
|
||||
Promise::Reject(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
|
||||
JS::Handle<JS::Value> aValue, ErrorResult& aRv)
|
||||
JS::Handle<JS::Value> aValue,
|
||||
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aRv)
|
||||
{
|
||||
// Implementation of
|
||||
// http://www.ecma-international.org/ecma-262/6.0/#sec-promise.reject
|
||||
|
||||
JSContext* cx = aGlobal.Context();
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global =
|
||||
do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!global) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<Promise> p = Reject(global, aGlobal.Context(), aValue, aRv);
|
||||
if (p) {
|
||||
p->mRejectionStack = p->mAllocationStack;
|
||||
// Steps 1 and 2.
|
||||
if (!aThisv.isObject()) {
|
||||
aRv.ThrowTypeError<MSG_ILLEGAL_PROMISE_CONSTRUCTOR>();
|
||||
return;
|
||||
}
|
||||
return p.forget();
|
||||
|
||||
// Step 3.
|
||||
PromiseCapability capability(cx);
|
||||
NewPromiseCapability(cx, global, aThisv, false, capability, aRv);
|
||||
// Step 4.
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
Promise* p = capability.mNativePromise;
|
||||
if (p) {
|
||||
p->MaybeRejectInternal(cx, aValue);
|
||||
p->mRejectionStack = p->mAllocationStack;
|
||||
} else {
|
||||
JS::Rooted<JS::Value> value(cx, aValue);
|
||||
JS::Rooted<JS::Value> ignored(cx);
|
||||
if (!JS::Call(cx, JS::UndefinedHandleValue /* thisVal */,
|
||||
capability.mReject, JS::HandleValueArray(value),
|
||||
&ignored)) {
|
||||
// Step 6.
|
||||
aRv.NoteJSContextException();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 7.
|
||||
aRetval.set(capability.PromiseValue());
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<Promise>
|
||||
|
|
|
@ -172,9 +172,10 @@ public:
|
|||
Resolve(nsIGlobalObject* aGlobal, JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<Promise>
|
||||
static void
|
||||
Reject(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
|
||||
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
|
||||
JS::Handle<JS::Value> aValue,
|
||||
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<Promise>
|
||||
Reject(nsIGlobalObject* aGlobal, JSContext* aCx,
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<script type="application/javascript"><!--
|
||||
|
||||
function runTest() {
|
||||
[{}, {}, {}, {}, {}].reduce(Promise.reject);
|
||||
[{}, {}, {}, {}, {}].reduce(Promise.reject.bind(Promise));
|
||||
ok(true, "No leaks with reject?");
|
||||
|
||||
[{}, {}, {}, {}, {}].reduce(Promise.resolve.bind(Promise));
|
||||
|
|
|
@ -205,6 +205,19 @@ function testResolve3() {
|
|||
).then(nextTest);
|
||||
}
|
||||
|
||||
function testReject1() {
|
||||
var p = win.Promise.reject(5);
|
||||
ok(p instanceof win.Promise, "Promise.reject should return a promise");
|
||||
p.then(
|
||||
function(arg) {
|
||||
ok(false, "Promise should be rejected");
|
||||
},
|
||||
function(e) {
|
||||
is(e, 5, "Should get correct Promise.reject value");
|
||||
}
|
||||
).then(nextTest);
|
||||
}
|
||||
|
||||
var tests = [
|
||||
testLoadComplete,
|
||||
testHaveXray,
|
||||
|
@ -220,6 +233,7 @@ var tests = [
|
|||
testResolve1,
|
||||
testResolve2,
|
||||
testResolve3,
|
||||
testReject1,
|
||||
];
|
||||
|
||||
function nextTest() {
|
||||
|
|
|
@ -25,8 +25,8 @@ interface _Promise {
|
|||
// return value of PromiseSubclass.resolve/reject to be a Promise object.
|
||||
[NewObject, Throws]
|
||||
static any resolve(optional any value);
|
||||
[NewObject]
|
||||
static Promise<void> reject(optional any value);
|
||||
[NewObject, Throws]
|
||||
static any reject(optional any value);
|
||||
|
||||
// The [TreatNonCallableAsNull] annotation is required since then() should do
|
||||
// nothing instead of throwing errors when non-callable arguments are passed.
|
||||
|
|
|
@ -294,7 +294,7 @@ var RootFolder = function (rootId, rootName) {
|
|||
result.parent = guidResult;
|
||||
return Promise.resolve(result);
|
||||
},
|
||||
Promise.reject
|
||||
Promise.reject.bind(Promise)
|
||||
);
|
||||
promises.push(promise);
|
||||
});
|
||||
|
@ -310,7 +310,7 @@ var RootFolder = function (rootId, rootName) {
|
|||
result.annos = annos;
|
||||
return Promise.resolve(result);
|
||||
},
|
||||
Promise.reject
|
||||
Promise.reject.bind(Promise)
|
||||
);
|
||||
promises.push(promise);
|
||||
});
|
||||
|
@ -352,7 +352,7 @@ var RootFolder = function (rootId, rootName) {
|
|||
result.parent = guidResult;
|
||||
return Promise.resolve(result);
|
||||
},
|
||||
Promise.reject
|
||||
Promise.reject.bind(Promise)
|
||||
);
|
||||
promises.push(promise);
|
||||
});
|
||||
|
@ -559,7 +559,7 @@ var RootFolder = function (rootId, rootName) {
|
|||
continue;
|
||||
}
|
||||
|
||||
let promise = exists(item).then(handleSortedItem, Promise.reject);
|
||||
let promise = exists(item).then(handleSortedItem, Promise.reject.bind(Promise));
|
||||
promises.push(promise);
|
||||
}
|
||||
|
||||
|
@ -588,7 +588,7 @@ var RootFolder = function (rootId, rootName) {
|
|||
function () {
|
||||
return _createItem(root);
|
||||
},
|
||||
Promise.reject
|
||||
Promise.reject.bind(Promise)
|
||||
);
|
||||
let items = [].concat(root._children);
|
||||
|
||||
|
@ -599,7 +599,7 @@ var RootFolder = function (rootId, rootName) {
|
|||
function () {
|
||||
return _createItem(item);
|
||||
},
|
||||
Promise.reject
|
||||
Promise.reject.bind(Promise)
|
||||
);
|
||||
}
|
||||
promises.push(promise);
|
||||
|
|
|
@ -206,4 +206,15 @@ promise_test(function testPromiseResolve() {
|
|||
});
|
||||
}, "Promise.resolve behavior");
|
||||
|
||||
promise_test(function testPromiseReject() {
|
||||
clearLog();
|
||||
var p = LoggingPromise.reject(5);
|
||||
var log = takeLog();
|
||||
assert_array_equals(log, ["Reject 1", "Constructor 1"]);
|
||||
|
||||
return p.catch(function(arg) {
|
||||
assert_equals(arg, 5);
|
||||
});
|
||||
}, "Promise.reject behavior");
|
||||
|
||||
</script>
|
||||
|
|
Загрузка…
Ссылка в новой задаче