[英]Resolve promise with an object with a “then” function
这是一个抽象的问题,因为我现在没有特定的用例。 我注意到如果你以承诺解决了承诺
var deferredA = $q.defer();
var deferredB = $q.defer();
deferredA.promise.then(function(result) {
// Will get here once promiseB has been resolved.
});
deferredA.resolve(deferredB.promise);
在promiseB已经解决之前,promiseA实际上并未解决(然后使用promiseB的解析值解析promiseA)。 但是,如果我想使用“then”函数解析对象的值,如下所示:
var deferred = $q.defer();
deferred.promise.then(function(result) {
// Aim is to get here with result = {then:function(){}},
// as though I had resolved a promise with a non-promise value,
// but this function is never called
});
deferred.resolve({
then: function() {
}
});
然后,promiseA从未实际得到解决,因为它假设值是一个promise,即使在上面的例子中它不是,因为它不是用$ q.defer()创建的。 有一个例子plunkr在
http://plnkr.co/edit/Z8XUKzxHtGBKBmgPed2q?p=preview
有没有解决的办法? 如果是这样,怎么样?
编辑 :澄清延迟/承诺并放入示例“然后”回调。
您传入的then
属性将覆盖promise的then
属性。 你想要从角度承诺的成功回调中返回你的对象then
像这样的函数:
$scope.resolvePromise2 = function() {
deferred2.resolve({
then: function(successCB) {
successCB({myResult1:'result1',
myResult2:'result2',
'then':function() {console.log("got here")}});
}
});
};
现在调用上面的消息,您可以调用属性中的then
函数:
promise2.then(function(result) {
//Now we get here
$scope.messages2.push('Promise 2 then callback. Result is:' + result);
result.then();
});
这是你最新的工作插件 。
resolve()
:
resolve: function(val) { if (pending) { var callbacks = pending; pending = undefined; value = ref(val); if (callbacks.length) { nextTick(function() { var callback; for (var i = 0, ii = callbacks.length; i < ii; i++) { callback = callbacks[i]; value.then(callback[0], callback[1], callback[2]); } }); } } },
看看value = ref(val);
接下来是value.then(callback[0], callback[1], callback[2]);
我们看到Angular将then
函数作为属性附加到promise,并且您传入的对象会覆盖该属性。 因此,在您的情况下,调用传入的then
函数而不是deferred.promise.then(function(result)...
但Angular使用三个回调调用你的then
函数 (success,error,notify): value.then(callback[0], callback[1], callback[2]);
在var callbacks = pending;
中保存的var callbacks = pending;
因此,解决方案是在then
函数中调用第一个“success”回调函数,并将对象(包括要返回的then
属性)传递给它。 现在,承诺then
被调用并接收您的对象,包括您的then
属性
then: function(successCB) { successCB({myResult1:'result1', myResult2:'result2', 'then':function() {console.log("got here")}}); }
你说{then:function(){...}}不是承诺。 那么,相应的承诺A +规范它。
规范声明promises应该是可互操作的,如果一个promise用一个可能的对象解决,或者一个promise的onFulfill回调返回了一个,那就说。 一旦onFulfill返回的promise或作为参数传递给resolve方法的promise得到解决,第一个promise的then方法返回的promise将立即得到解决。
因此,您的承诺永远不会解决,因为您的可用对象永远不会被“解析”,并且永远不会调用其onFulfill回调。
这有点令人困惑,但让我们看看练习。
var deferred = $q.defer();
deferred.promise.then(function(result) {
// A promise should not be resolved with another
});
deferred.resolve({
then: function() {
}
});
延迟的解决方法将看到你的对象的then方法,并思考:“呃,姐姐的承诺,我会尽快得到解决”。 所以它会通过回调调用你的then函数来实际解决你的承诺。
这条路:
yourThenable.then(function(spectedData){
// Your promise will resolve as soon as this callback gets called
// But your then function doesnt call the onFulfill callback
// Thats why it never resolves
}, function(spectedData){
// Also if this second parameter gets called your promise will be rejected
});
我不知道你为什么要这样做,但你不应该用一个可靠的方法解决一个承诺。 你可以用另一种方式思考你想要的东西。
这是我能想到的最简单的:
deferred.resolve([{
then: function() {
}
}]);
resolve方法将查找then方法,但现在您的对象不是一个可用的,该数组的0索引是。
deferred.promise.then(function(result) {
// Now you have a result that is a Array
// And the index 0 is your thenable object
});
但是,在继续这样做之前,你应该再三思。
我得出的结论是,这是不可能的。 你只能确保你不必then
通过包装另一个对象中的对象,而一个属性:
var deferred = $q.defer();
deferred.promise.then(function(result) {
// Aim is to get here with result = {then:function(){}},
// as though I had resolved a promise with a non-promise value,
// but this function is never called
result.result.then
});
deferred.resolve({ result: {
then: function() {}
}});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.