解释在 Parse 的 for 循环中执行 find 函数背后的逻辑
Explain the logic behind the execution of find function inisde for loop in Parse
下面是代码:
function f1() {
for (var i = 0; i < arr.length; i++) {
var query = new Parse.Query("Group");
query.equalTo("parent", arr[i]);
var position = pos[i];
alert("pos[i] = " + pos[i] + " position = " + position);
query.find({
success: function(users) {
if (users.length === 0) {
alert("in if");
} else {
alert("in else");
}
}
});
}
}
基本上,Group 是 Parse 类,arr 包含 Class Parse.User 的对象,pos 是存储整数的数组 现在包含 2 个整数:8、15 并且 arr 包含两个值对于 i = 0 users.length != 0 和对于 i = 1,users.length = 0。所以基本上,当这个函数被调用时,我想要的输出是:
pos[i] = 8 position = 8
in else
pos[i] = 15 position = 15
in if
但实际上,我明白了:
pos[i] = 8 position = 8
pos[i] = 15 position = 15 // I don't know why i am getting this, it is irritating me
in else
pos[i] = 15 position = 15
in if
我已经在互联网和 google 上搜索过这个问题,但找不到更好的解决方案。那么如何得到想要的输出呢?
注意:切勿使用 alert
进行调试,当事情发生时,您会被它所产生的影响所误导。几乎总是,您想使用浏览器内置的调试器。在连时间都弄乱的情况下,通过 console.log
.
记录事情
但这里的主要问题是 query.find
调用的工作是 异步的 ,它稍后会在循环完成后调用 success
函数。
如果您想知道找到了什么位置等,您可以将该信息绑定到您的 success
回调并让它输出:
var position = pos[i];
query.find({
// Note first arg v
success: function(pos, users) {
if (users.length === 0) {
console.log("in if, pos = " + pos);
} else {
console.log("in else, pos = " + pos);
}
}.bind(null, position) // *** Note bind
});
Function#bind
returns 一个新的 "bound" 函数,当被调用时,将调用具有给定 this
值的原始函数(上面未使用,因此初始null
),然后传递给 bind
的任何参数,然后传递给绑定函数的参数。
这可能有点难以理解,所以这里有一个更简单的例子:
function foo(a, b) {
snippet.log("a = " + a + ", b = " + b);
}
var f = foo.bind(null, 'one');
f('two'); // Shows a = one, b = two
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
如果你想按照严格的顺序执行它们,你必须等待一个调用完成才能开始下一个调用:
function f1() {
var i = 0;
doOne();
function doOne() {
var query = new Parse.Query("Group");
var position = pos[i];
query.equalTo("parent", arr[i]);
query.find({
success: function(users) {
if (users.length === 0) {
alert("in if");
} else {
alert("in else");
}
if (++i < arr.length) {
doOne();
}
}
});
}
}
考虑使用 Promise.when() 如下:
var queries = [];
for (var i = 0; i < arr.length; i++) {
var query = new Parse.Query("Group");
query.equalTo("parent", arr[i]);
var position = pos[i];
alert("pos[i] = " + pos[i] + " position = " + position);
queries.push(query.find());
}
Parse.Promise.when(queries).then(function() {
var users = Array.prototype.slice.call(arguments);
// users will contain the results of each query in corresponding positions
});
想法是 find() returns 一个完成异步查找的承诺,而 Promise.when() returns 一个在所有承诺传递给它时实现的承诺已完成。
下面是代码:
function f1() {
for (var i = 0; i < arr.length; i++) {
var query = new Parse.Query("Group");
query.equalTo("parent", arr[i]);
var position = pos[i];
alert("pos[i] = " + pos[i] + " position = " + position);
query.find({
success: function(users) {
if (users.length === 0) {
alert("in if");
} else {
alert("in else");
}
}
});
}
}
基本上,Group 是 Parse 类,arr 包含 Class Parse.User 的对象,pos 是存储整数的数组 现在包含 2 个整数:8、15 并且 arr 包含两个值对于 i = 0 users.length != 0 和对于 i = 1,users.length = 0。所以基本上,当这个函数被调用时,我想要的输出是:
pos[i] = 8 position = 8
in else
pos[i] = 15 position = 15
in if
但实际上,我明白了:
pos[i] = 8 position = 8
pos[i] = 15 position = 15 // I don't know why i am getting this, it is irritating me
in else
pos[i] = 15 position = 15
in if
我已经在互联网和 google 上搜索过这个问题,但找不到更好的解决方案。那么如何得到想要的输出呢?
注意:切勿使用 alert
进行调试,当事情发生时,您会被它所产生的影响所误导。几乎总是,您想使用浏览器内置的调试器。在连时间都弄乱的情况下,通过 console.log
.
但这里的主要问题是 query.find
调用的工作是 异步的 ,它稍后会在循环完成后调用 success
函数。
如果您想知道找到了什么位置等,您可以将该信息绑定到您的 success
回调并让它输出:
var position = pos[i];
query.find({
// Note first arg v
success: function(pos, users) {
if (users.length === 0) {
console.log("in if, pos = " + pos);
} else {
console.log("in else, pos = " + pos);
}
}.bind(null, position) // *** Note bind
});
Function#bind
returns 一个新的 "bound" 函数,当被调用时,将调用具有给定 this
值的原始函数(上面未使用,因此初始null
),然后传递给 bind
的任何参数,然后传递给绑定函数的参数。
这可能有点难以理解,所以这里有一个更简单的例子:
function foo(a, b) {
snippet.log("a = " + a + ", b = " + b);
}
var f = foo.bind(null, 'one');
f('two'); // Shows a = one, b = two
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
如果你想按照严格的顺序执行它们,你必须等待一个调用完成才能开始下一个调用:
function f1() {
var i = 0;
doOne();
function doOne() {
var query = new Parse.Query("Group");
var position = pos[i];
query.equalTo("parent", arr[i]);
query.find({
success: function(users) {
if (users.length === 0) {
alert("in if");
} else {
alert("in else");
}
if (++i < arr.length) {
doOne();
}
}
});
}
}
考虑使用 Promise.when() 如下:
var queries = [];
for (var i = 0; i < arr.length; i++) {
var query = new Parse.Query("Group");
query.equalTo("parent", arr[i]);
var position = pos[i];
alert("pos[i] = " + pos[i] + " position = " + position);
queries.push(query.find());
}
Parse.Promise.when(queries).then(function() {
var users = Array.prototype.slice.call(arguments);
// users will contain the results of each query in corresponding positions
});
想法是 find() returns 一个完成异步查找的承诺,而 Promise.when() returns 一个在所有承诺传递给它时实现的承诺已完成。