然后分配给变量然后捕获

Assign to variable after then catch

我在 angularJS 中有一个 $watchCollection,它调用监听器中的函数 getBalance(addr)

$scope.$watchCollection('settings',
  function() {
    for (i = 0; i < $scope.settings['accounts'].length; i++) {
      var bal = $scope.getBalance($scope.settings['accounts'][i]);
      console.log(bal);
    }
  }
);

函数getBalance定义如下:

$scope.getBalance = function(addr) {
  var balance;
  if ($scope.settings.contract !== null) {
    $scope.settings.contract.deployed().then(function(deployed) {
      return deployed.balanceOf(addr);
    }).then(function(res) {
       balance = res.toNumber();
       console.log(balance);
       return balance;
    }).catch(function(err) {
      console.log(err.message);
    });
  }
  return balance;
};

问题是在 then 中,balance 变量打印正确,但是在 $watchCollection 中,return 是 undefined

问题应该是因为 JS 一直在执行而不等待结果,因此变量被读取为 undefined 但是,我如何更改这两段代码才能在准备好时获得结果并将其附加到 $scope.balance.

您似乎在尝试将异步代码更改为同步代码,但实际上您做不到。你需要始终贯彻承诺,两者兼而有之。

与其将 balance 设置为变量并 returning 该变量,return 承诺本身,然后在 $watchCollection 中使用 then 来获取值。

$scope.$watchCollection('settings',
  function() {
    for (i = 0; i < $scope.settings['accounts'].length; i++) {
      $scope.getBalance($scope.settings['accounts'][i])
        .then(bal => console.log(bal));
    }
  }
);

$scope.getBalance = function(addr) {
  if ($scope.settings.contract !== null) {
    return $scope.settings.contract.deployed().then(function(deployed) {
      return deployed.balanceOf(addr);
    }).then(function(res) {
       balance = res.toNumber();
       console.log(balance);
       return balance;
    }).catch(function(err) {
      console.log(err.message);
    });
  }

  return Promise.resolve(null);
};

注意,在 return Promises 的函数中,确保所有路径 return a Promise 否则会发生不好的事情(因此 Promise.resolve(null)) .