关于我必须编写的代码,我在这里有点绑定。 目前我正在尝试迭代一串字符串。找到某个文本后,如果值为true,则该值绑定到temporaryObject.img。之后,必须对服务器进行调用,以便检索某些信息并将其绑定到与第二个属性(temporaryObject.url)相同的temporaryObject。不幸的是,调用可能在迭代完成后解决,因为它没有添加这个添加从调用到Object中的服务器的url。我使用的库是angularjs和jquery。
这是我写的代码的一部分。
$scope.Data = [];
var strArray = ["img1", "link", "img2", "link2", "img3", "link3"];
var re1 = /<img/;
for(var i = 0 ; i < strArray.length ; i++) {
var tempObject = {};
var test = re1.test(strArray[i]);
if (test){
tempObject.img = strArray[i + 1];
myAngularService.getServerInformation().then(function(result){
tempObject.url = result;
$scope.Data.push(tempObject);
}
}
不幸的是,来自服务器的信息没有在迭代完成的同时到达或出现问题,因为$ scope.Data将不包含从服务器请求的url。任何建议如何使用这种代码的承诺将不胜感激。我试着搜索每一个可能的解决方案,但没有用。
答案 0 :(得分:1)
Javascript是功能范围的。换句话说:
if (true) {
var testing = 5;
}
console.log(testing); // Logs 5
将此应用于您的示例,tempObject
回调函数中的.then
都引用了相同的变量!
一种解决方案是在for语句中使用Immediately-Invoked Function Expression(IIFE)来创建新范围:
for(var i = 0 ; i < strArray.length ; i++) {
(function() {
var tempObject = {}; // Is now declared within the new function
/* ... code here ... */
})();
}
另一种解决方案是简单地使用$.each
(或angular.forEach):
$.each(strArray, function(index, value) {
var tempObject = {}; // Is now declared within the new function
/* ... code here ... */
});
关于等待所有通话结束,一种解决方案是将您的承诺存储在数组中使用有角度的$q服务:
$scope.Data = [];
var promises = [];
var strArray = ["img1", "link", "img2", "link2", "img3", "link3"];
var re1 = /img/;
$.each(strArray, function (index, value) {
var tempObject = {};
var test = re1.test(value);
if (test) {
tempObject.img = strArray[index + 1];
var myPromise = myAngularService.getServerInformation();
myPromise.then(function (result) {
tempObject.url = result;
$scope.Data.push(tempObject);
}
promises.push(myPromise);
}
})
$q.all(promises).then(function() {
// All calls will have finished
console.log($scope.Data);
}, function() {
// At least 1 call failed!
console.log("an error occurred!");
});