angularjs - 使用具有 "then"函数的对象解析 Promise

标签 angularjs promise

这是一个有点抽象的问题,因为我现在没有特定的用例。我注意到,如果你用一个 promise 来解决一个 promise

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 并没有真正被解析(然后promiseA 用promiseB 的解析值来解析)。但是,如果我想用带有“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

有办法解决这个问题吗?如果是这样,怎么办?

编辑:澄清延迟/ promise 并放入“then”回调示例。

最佳答案

解决方案

then您传入的属性会覆盖 promise 的 then属性(property)。相反,您希望从 Angular promise then 的成功回调中返回对象。功能如下:

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

使用上面的内容,您的消息现在已被调用,您可以调用 then在您的属性(property)中发挥作用:

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

这是您更新的 working plunker

问题/为什么它有效

让我们看看 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具有三个回调的函数(成功、错误、通知):value.then(callback[0], callback[1], callback[2]);被保存在 var callbacks = pending;

所以解决方案是在 then 中调用第一个“成功”回调函数并将其传递给您的对象,包括 then您想要归还的属性(property)。现在 promise 的then被调用并接收您的对象,包括您的 then属性(property)

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

关于angularjs - 使用具有 "then"函数的对象解析 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20455632/

相关文章:

javascript - GraphQL:在文件上传期间解决 promise 时出错

javascript - 调用 Promise.all() 时如何提供有关 Promise 的元数据?

javascript - 使用 json 和 $http 从 php 数组自动完成 Angular js

javascript - Angular 显示/隐藏仅适用于第二个函数调用,应用/摘要问题?

angular - 如何确保在从类调用函数之前完成构造函数/ngOnInit?

带有 map 的 Javascript ES6 Promises

coffeescript - $q defer 和 Promise 以及如何使用它们在渲染 View 之前为 Controller 加载数据

angularjs - 当 columnDefs 将字段作为类型编号时,Angular ui 网格正在按字符串过滤。为什么?

javascript - angularJS:为什么绑定(bind)到指令内的范围会导致 ng-repeat 的内容丢失?

javascript - AngularJS - 预加载应用程序设置