在Angular服务调用中确定范围

Mat*_*nis 5 javascript angularjs

我很困惑为什么我不能按要求执行此服务调用.该console.log范围内的definitionsService.get承诺,决心是我所期待的(对象我的目标返回).然而在console.log我回来之前正确的defsundefined哪个,当然是指我的返回值是不确定的.我错过了什么?

function getDefinitions() {
  var defs;
  definitionsService.get().$promise.then(function(data) {
    console.log(data);
    defs = data;
    console.log(defs);
  });
  console.log(defs);
  return defs;
};
Run Code Online (Sandbox Code Playgroud)

我把上面改为:

function getDefinitions() {
  var defs = $q.defer();
  definitionsService.get().$promise.then(function(data) {
    defs.resovle(data);
  });
  return defs.promise;
};
Run Code Online (Sandbox Code Playgroud)

根据以下答案.

我也按照相同的答案更改了我调用此方法的方式:

function detail(account) {
  getDefinitions().then(function(definitions) {
    var key = angular.isDefined(definitions.ABC[account.code]) ? account.code : '-';
    return definitions.ABC[key].detail;
  });
}
Run Code Online (Sandbox Code Playgroud)

然后在我的控制器中,我正在尝试执行以下操作:

var getAccounts = function() {
  playersService.getAccounts({
    playerId: playerId
  }).$promise.then(function(accounts) {
    for (var i = 0; i < accounts.length; i++) {
      accounts[i].detail = utilitiesService.detail(accounts[i]);
    }
    vm.accounts = accounts;
  });
};

var init = function() {
  getAccounts();
};

init();
Run Code Online (Sandbox Code Playgroud)

我的问题accounts[i].detail是一贯的undefined.

Tom*_*man 2

欢迎来到异步调用的世界。

如果您在 getDefinitions(来自 definitonsService)内进行异步调用,那么您必须假设 getDefinitions() 也是异步的。这意味着你不能简单地返回 def。

当您在返回之前打印 defs 时,服务的异步调用尚未执行。

defs 也应该是一个 Promise 对象。然后你可以像你一样返回它,但是调用它的方法也应该将它与 .then(function(defs)...

或者以代码形式:

function getDefinitions() {
  var defs = $q.defer();
  definitionsService.get().$promise.then(function(data) {
    defs.resovle(data);
  });
  return defs.promise;
};
Run Code Online (Sandbox Code Playgroud)

无论谁打电话getDefinitions()

getDefinitions().then(function(defs) {
 // do something with defs...
}
Run Code Online (Sandbox Code Playgroud)

编辑后回答问题:

问题再次出在 getAccounts 方法内部的异步性质上。utilityService.detail 是一个异步方法。因此,您实际上是将承诺而不是值分配给accounts[i].detail。

由于每个帐户都需要一个异步调用,因此使用 $q.all 似乎是一个好主意:

var promises = [];
for (var i = 0; i < accounts.length; i++) {
      promises.push(utilitiesService.detail(accounts[i]));
    }
$q.all(promises).then(function(values)){
 // you should have all the account details inside 'values' and can update vm.accounts
}
Run Code Online (Sandbox Code Playgroud)

请记住- 获得承诺是同步的。获得承诺的价值……好吧,承诺给你——这是异步的。