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

Mic*_*mza 3 promise angularjs

这是一个抽象的问题,因为我现在没有特定的用例.我注意到如果你以承诺解决了承诺

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);
Run Code Online (Sandbox Code Playgroud)

在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() {
  }
});
Run Code Online (Sandbox Code Playgroud)

然后,promiseA从未实际得到解决,因为它假设值是一个promise,即使在上面的例子中它不是,因为它不是用$ q.defer()创建的.有一个例子plunkr在

http://plnkr.co/edit/Z8XUKzxHtGBKBmgPed2q?p=preview

有没有解决的办法?如果是这样,怎么样?

编辑:澄清延迟/承诺并放入示例"然后"回调.

Kay*_*ave 5

then您传入的财产将覆盖承诺的then财产.你想要从角度promises then函数的成功回调中返回你的对象,如下所示:

$scope.resolvePromise2 = function() {
    deferred2.resolve({
      then: function(successCB) {
        successCB({myResult1:'result1',
                  myResult2:'result2',
                  'then':function() {console.log("got here")}});
      }
    });
  };
Run Code Online (Sandbox Code Playgroud)

现在使用上面的消息调用,您可以then在您的属性中调用该函数:

promise2.then(function(result) {
   //Now we get here
   $scope.messages2.push('Promise 2 then callback. Result is:' + result);
   result.then();
});
Run Code Online (Sandbox Code Playgroud)

这是你最新的工作插件.

问题/为什么这样做

我们来看看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]);
          }
        });
      }
    }
  },
Run Code Online (Sandbox Code Playgroud)

看着value = ref(val);后面value.then(callback[0], callback[1], callback[2]);我们可以看到,折角的附加then功能的承诺作为属性和您在覆盖通过了属性的对象.因此,在您的情况下,then调用传入的函数而不是deferred.promise.then(function(result)....

Angular then使用三个回调(成功,错误,通知)调用您的函数:value.then(callback[0], callback[1], callback[2]);已保存var callbacks = pending;

因此,解决方案是在then函数内部调用第一个"成功"回调函数,并将对象(包括then要返回的属性)传递给它.现在,诺言then被召唤并收到你的对象,包括你的then财产

then: function(successCB) {
   successCB({myResult1:'result1',
              myResult2:'result2',
              'then':function() {console.log("got here")}});
}
Run Code Online (Sandbox Code Playgroud)