Javascript 推迟/推迟承诺解决

Javascript 推迟/推迟承诺解决,javascript,angularjs,promise,deferred,resolve,Javascript,Angularjs,Promise,Deferred,Resolve,我希望以与使用Javascript promise对象解析Angular的defer.resolve相同的方式解析promise对象。 换句话说:我想创建一个要返回的虚拟承诺对象。这一承诺将在稍后得到解决 我会这样写: ... $scope.checkThis = { test: false }; function getPromise() { var deferred = $q.defer(); var data = [1, 2, 3]; function reso

我希望以与使用Javascript promise对象解析Angular的defer.resolve相同的方式解析promise对象。 换句话说:我想创建一个要返回的虚拟承诺对象。这一承诺将在稍后得到解决

我会这样写:

...
$scope.checkThis = { test: false };

function getPromise() {
    var deferred = $q.defer();
    var data = [1, 2, 3];

    function resolvePromise() {
        deferred.resolve(data);
    }

    $scope.$watch("checkThis.test", function(newVal, oldVal) {
        if (newVal) {
            resolvePromise();
        }
    });

    return deferred.promise;
}

$scope.getData1 = function() {
    return getPromise();
};

$scope.getData2 = function() {
    return getPromise();
};

...
如何使用普通Javascript Promise对象实现同样的效果?我不知道如何使用承诺构造函数,因为有一个事件($scope.checkThis.test变为true)将触发多个解析。

标准承诺使用。有一种简单且首选的方法:

function getPromise() {
  return new Promise(resolve => {
    var data = [1, 2, 3];
    $scope.$watch("checkThis.test", function(newVal, oldVal) {
      if (newVal) {
        resolve(data);
      }
    });
  });
}
小心标准承诺不会触发角度摘要循环,对承诺回调中的作用域所做的更改可能不会立即反映在UI和观察者上。这就是您不能将
$q
承诺更改为标准
承诺的原因

如果出于某种原因,您无法将揭示构造函数模式应用于您的场景,那么下面是一种创建类似延迟类的方法记住,您总是可以避免使用此类,我只是将其留在这里,以便访问者了解如何在不需要重新构造现有代码的情况下从旧的promise库进行更改。任何新代码都不应使用此选项:

class Deferred {
  constructor() {
    this.resolve = null;
    this.reject = null;
    this.promise = null;

    this.promise = new Promise((resolve, reject) => {
      this.resolve = resolve;
      this.reject = reject;
    });
  }
}
标准承诺使用。有一种简单且首选的方法:

function getPromise() {
  return new Promise(resolve => {
    var data = [1, 2, 3];
    $scope.$watch("checkThis.test", function(newVal, oldVal) {
      if (newVal) {
        resolve(data);
      }
    });
  });
}
小心标准承诺不会触发角度摘要循环,对承诺回调中的作用域所做的更改可能不会立即反映在UI和观察者上。这就是您不能将
$q
承诺更改为标准
承诺的原因

如果出于某种原因,您无法将揭示构造函数模式应用于您的场景,那么下面是一种创建类似延迟类的方法记住,您总是可以避免使用此类,我只是将其留在这里,以便访问者了解如何在不需要重新构造现有代码的情况下从旧的promise库进行更改。任何新代码都不应使用此选项:

class Deferred {
  constructor() {
    this.resolve = null;
    this.reject = null;
    this.promise = null;

    this.promise = new Promise((resolve, reject) => {
      this.resolve = resolve;
      this.reject = reject;
    });
  }
}

这个
延迟的
类消除了揭示构造函数模式的所有优点。不要用它!如果我理解正确,您正在创建一个承诺工厂,返回一个待定的承诺。这在我的情况下有效。多谢各位@伯吉:为什么不使用它?@Bergi完全正确。我只在涉及分布式系统的场景中使用它,并且必须将基于消息的协议转换为基于呼叫响应的协议。在这种情况下,唯一的方法是将所有挂起的请求(例如延迟请求)存储在一个映射中,并在适当的响应中检索和解决它们。@CaseNonsitive请参阅Domenic博客的答案中的链接,@CaseNonsitive它的直观性和可读性较差。构造函数意味着使对象进入可用状态。但是
延迟的
构造函数不做这样的事情。仍然需要调用
deferred.resolve()
deferred.reject()
,对象才能实际使用。而且,这些函数可以在程序中的任何地方调用,因此很难遵循。Promise构造函数保证解析/拒绝条件都在同一个位置,并且您可以从
新Promise
返回的对象是一个完全可用的Promise。这个
延迟的
类消除了揭示构造函数模式的所有优点。不要用它!如果我理解正确,您正在创建一个承诺工厂,返回一个待定的承诺。这在我的情况下有效。多谢各位@伯吉:为什么不使用它?@Bergi完全正确。我只在涉及分布式系统的场景中使用它,并且必须将基于消息的协议转换为基于呼叫响应的协议。在这种情况下,唯一的方法是将所有挂起的请求(例如延迟请求)存储在一个映射中,并在适当的响应中检索和解决它们。@CaseNonsitive请参阅Domenic博客的答案中的链接,@CaseNonsitive它的直观性和可读性较差。构造函数意味着使对象进入可用状态。但是
延迟的
构造函数不做这样的事情。仍然需要调用
deferred.resolve()
deferred.reject()
,对象才能实际使用。而且,这些函数可以在程序中的任何地方调用,因此很难遵循。Promise构造函数保证解析/拒绝条件都在同一个位置,并且您可以从
新Promise
返回的对象是完全可用的Promise。您所说的“将触发多个解析的事件”是什么意思?为什么这对延迟有效,但对承诺构造函数无效?您所说的“将触发多个解决的事件”是什么意思?为什么这对延期有效而对承诺构建者无效?