提前感谢您的帮助。 我正在使用Phonegap和Javascript进行练习分配。长话短说:我需要使用Parse.com来存储一些乐高人仔的信息。我现在遇到的问题主要是由于我对Javascript的经验不足。
我正在努力让用户为数字添加标签。用户输入它们,用逗号分隔,然后我拆分字符串。那工作正常。
现在,我需要将尚不存在的标记添加到我的数据库中。为此,我搜索具有该描述的任何标签(使用query.find)然后,如果它存在,我不创建它,我只是修改关系。如果它不存在,我创建它然后修改关系。
我的问题是:我似乎无法从query.find的成功回调中访问标记描述(字符串)。由于范围的原因,我非常确定。除了结果数组之外,还有任何正确的方法可以使用成功回调来访问变量吗?
我目前的代码如下:
var Figure = Parse.Object.extend("Figure");
var Tag = Parse.Object.extend("Tag");
var nombre = $('#nombre').val();
var serie = $('#serie').val();
var figure = new Figure({"Name":nombre,"Series":serie});
var tags = $('#tags').val();
res = tags.split(","); //split the
figure.save().then(function() {
for (var i = 0; i < res.length; i++) { //for each tag
var query = new Parse.Query(Tag); //create the query.
query.equalTo("Description", res[i]);
query.find( {//execute query
success: function(results, res[i]) {
if (results.length > 0){ //if there are results.
var tag = results[0]; //get the tag
var relation_tag = tag.relation("figures"); //get the relation
relation_tag.add(figure); //add figure to relation
tag.save();
}
else { //if there are no results, the tag does not exist.
new_tag = new Tag({"Description":res[i]});
//ABOVE THIS LINE: res[i] is always undefined.
var relation_tag = new_tag.relation("figures"); //get the relation
relation_tag.add(figure); //add the figure
new_tag.save();
}
},
//error with query
error: function() {
alert("ERROR");
}
});
}
}, function(error) {
alert("No se pudo guardar la figura");
});
在成功回调中,res [i]总是未定义,我认为是因为范围。
答案 0 :(得分:5)
这是异步Javascript编程中非常常见的问题。你正在做这样的事情:
for (var i = 0; i < array.length; i++) {
anAsyncFunction(function(result) { // inner function
doSomethingWith(array[i]);
}
}
问题在于,Javascript函数通过引用而不是值存储外部变量,这意味着函数在执行时从外部作用域查找变量的值,而不是在定义时查找。由于代码是异步的,因此在for循环完成后调用内部函数,此时我们有i === array.length
,所以array[i] === array[array.length] === undefined
。
为避免这种情况,您可以使用立即调用的函数表达式(IIFE,发音为&#34; iffy&#34;):
for (var i = 0; i < array.length; i++) {
anAsyncFunction((function(j) { // IIFE
return function innerFunction(result) { // inner function
doSomethingWith(array[j]); // j instead of i
}
})(i); // passing "value of i"
}
因为立即调用IIFE,所以当前值为i
并传递并存储到j
中,当内部函数执行时,它使用正确的值。
所以在你的情况下这应该有效:
success: (function(j) { // IIFE
return function(results) {
if (results.length > 0) {
var tag = results[0];
var relation_tag = tag.relation("figures");
relation_tag.add(figure);
tag.save();
}
else { //if there are no results, the tag does not exist.
new_tag = new Tag({"Description":res[j]}); // j instead of i
var relation_tag = new_tag.relation("figures");
relation_tag.add(figure);
new_tag.save();
}
}
})(i) // pass "value of i"
如果您愿意,您也可以将描述本身而不仅仅是索引传递给IIFE(我想我会这样做):
success: (function(description) { // IIFE
return function(results) {
if (results.length > 0) {
var tag = results[0];
var relation_tag = tag.relation("figures");
relation_tag.add(figure);
tag.save();
}
else { //if there are no results, the tag does not exist.
new_tag = new Tag({"Description":description}); // description
var relation_tag = new_tag.relation("figures");
relation_tag.add(figure);
new_tag.save();
}
}
})(res[i]) // pass description
答案 1 :(得分:0)
var Tag = Parse.Object.extend("Tag");
var query = new Parse.Query(Tag);