在解决 angular 承诺时保留对调用对象的引用
Keep reference to the calling object when resolving an angular promise
问题
当解决承诺时,javascript 上下文更改为 Window #
- 这意味着我无法引用正在解决承诺的对象,也无法使用或更改其任何变量。
如果我使用 that = this
hack,我可以参考它,但问题是如果我有多个对象使用这个 hack,它们将共享相同的 window.that
变量并且它们会混淆的。
这是我为演示此问题而创建的一些示例代码:
app.js
var app = angular.module('myApp', []);
//Represents a service that makes call to the server.
//Returns angular promises
app.service('MyService', function($q, $timeout){
this.evenOrOdd = function(i){
console.log("even or odd for: " + i);
var deffered = $q.defer();
$timeout(function(){
console.log("starting time out");
if (parseInt(i)) {
if (i%2 === 1) deffered.resolve("Odd:" + i);
else deffered.resolve("Even" + i);
}
else deffered.reject("That's not an int!");
}, 3000);
return deffered.promise;
};
});
//Represents some business object
//We may want several of these
app.factory('MyFactory', function(MyService){
return function() {
//Some object specific variable
this.rand = Math.random();
console.log("creating new factory object with rand = " + this.rand);
this.oddCheck = function(i){
var promise = MyService.evenOrOdd(i);
that = this; //the problem is here
promise.then(function(value){
console.log(that.rand + "|" + value);
}
);
promise.catch(function(value){
console.log(that.rand + "|" + value);
});
};
};
});
//Our controller, makes calls to update multiple objects at the same time
app.controller('MyController', function($scope, MyFactory) {
$scope.factoryObject = new MyFactory();
$scope.factoryObject2 = new MyFactory();
$scope.myClick = function(){
$scope.factoryObject.oddCheck(10);
$scope.factoryObject2.oddCheck(11);
};
}
);
index.html
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js" type ="text/javascript"></script>
<script src = "app.js" type ="text/javascript"></script>
</head>
<body ng-app="myApp" >
<div ng-controller = "MyController">
<button ng-click = "myClick()">Click me</button>
</div>
</body>
</html>
当我们 运行 时,我们得到:
creating new factory object with rand = 0.10776704256566871
app.js (line 38)
creating new factory object with rand = 0.5952598424233105
app.js (line 38)
even or odd for: 10
app.js (line 8)
even or odd for: 11
app.js (line 8)
starting time out
app.js (line 12)
0.5952598424233105|Even10 //Rand is wrong
app.js (line 46)
starting time out
app.js (line 12)
0.5952598424233105|Odd:11
app.js (line 46)
在解决 promise 时,我还能如何跟踪对象的位置?
尝试 var that = this;
否则你使用的是一个一直被覆盖的全局变量 - 或者查看绑定 - 例如
this.oddCheck = function(i){
var promise = MyService.evenOrOdd(i);
promise.then(function(value){
console.log(this.rand + "|" + value);
}.bind(this));
promise.catch(function(value){
console.log(this.rand + "|" + value);
}.bind(this));
};
最后 - 上面的函数也可以这样写:
this.oddCheck = function(i){
MyService.evenOrOdd(i)
.then(function(value){
console.log(this.rand + "|" + value);
}.bind(this))
.catch(function(value){
console.log(this.rand + "|" + value);
}.bind(this));
};
我更喜欢这样使用。你应该 return 反对。您可以在该对象内部引用自身。这是示例:http://jsbin.com/memaha/12/edit?js,console
您也可以使用 Ecmascript 6 箭头函数。它提供父上下文。.then(res => console.log(this.rand)//this will be outter function)
问题
当解决承诺时,javascript 上下文更改为 Window #
- 这意味着我无法引用正在解决承诺的对象,也无法使用或更改其任何变量。
如果我使用 that = this
hack,我可以参考它,但问题是如果我有多个对象使用这个 hack,它们将共享相同的 window.that
变量并且它们会混淆的。
这是我为演示此问题而创建的一些示例代码:
app.js
var app = angular.module('myApp', []);
//Represents a service that makes call to the server.
//Returns angular promises
app.service('MyService', function($q, $timeout){
this.evenOrOdd = function(i){
console.log("even or odd for: " + i);
var deffered = $q.defer();
$timeout(function(){
console.log("starting time out");
if (parseInt(i)) {
if (i%2 === 1) deffered.resolve("Odd:" + i);
else deffered.resolve("Even" + i);
}
else deffered.reject("That's not an int!");
}, 3000);
return deffered.promise;
};
});
//Represents some business object
//We may want several of these
app.factory('MyFactory', function(MyService){
return function() {
//Some object specific variable
this.rand = Math.random();
console.log("creating new factory object with rand = " + this.rand);
this.oddCheck = function(i){
var promise = MyService.evenOrOdd(i);
that = this; //the problem is here
promise.then(function(value){
console.log(that.rand + "|" + value);
}
);
promise.catch(function(value){
console.log(that.rand + "|" + value);
});
};
};
});
//Our controller, makes calls to update multiple objects at the same time
app.controller('MyController', function($scope, MyFactory) {
$scope.factoryObject = new MyFactory();
$scope.factoryObject2 = new MyFactory();
$scope.myClick = function(){
$scope.factoryObject.oddCheck(10);
$scope.factoryObject2.oddCheck(11);
};
}
);
index.html
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js" type ="text/javascript"></script>
<script src = "app.js" type ="text/javascript"></script>
</head>
<body ng-app="myApp" >
<div ng-controller = "MyController">
<button ng-click = "myClick()">Click me</button>
</div>
</body>
</html>
当我们 运行 时,我们得到:
creating new factory object with rand = 0.10776704256566871
app.js (line 38)
creating new factory object with rand = 0.5952598424233105
app.js (line 38)
even or odd for: 10
app.js (line 8)
even or odd for: 11
app.js (line 8)
starting time out
app.js (line 12)
0.5952598424233105|Even10 //Rand is wrong
app.js (line 46)
starting time out
app.js (line 12)
0.5952598424233105|Odd:11
app.js (line 46)
在解决 promise 时,我还能如何跟踪对象的位置?
尝试 var that = this;
否则你使用的是一个一直被覆盖的全局变量 - 或者查看绑定 - 例如
this.oddCheck = function(i){
var promise = MyService.evenOrOdd(i);
promise.then(function(value){
console.log(this.rand + "|" + value);
}.bind(this));
promise.catch(function(value){
console.log(this.rand + "|" + value);
}.bind(this));
};
最后 - 上面的函数也可以这样写:
this.oddCheck = function(i){
MyService.evenOrOdd(i)
.then(function(value){
console.log(this.rand + "|" + value);
}.bind(this))
.catch(function(value){
console.log(this.rand + "|" + value);
}.bind(this));
};
我更喜欢这样使用。你应该 return 反对。您可以在该对象内部引用自身。这是示例:http://jsbin.com/memaha/12/edit?js,console
您也可以使用 Ecmascript 6 箭头函数。它提供父上下文。.then(res => console.log(this.rand)//this will be outter function)