繁体   English   中英

使用具有“then”功能的对象解析promise

[英]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();
});

这是你最新的工作插件

问题/为什么这样做

我们来看看Angular 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM