#javascript #facebook #for-loop
#javascript #Facebook #цикл for
Вопрос:
Я пытаюсь создать скрипт, который 1) Считывает идентификаторы пользователей FB из полей текстового ввода и преобразует их в массив 2) вызывает FB.api с каждым из идентификаторов для имени пользователя и сохраняет возвращенное значение имени пользователя в другой массив. Проблема: по какой-то причине все первые имена, полученные из FB.api, сохраняются в том же индексе массива, который занимает 5 место. Что особенно странно, поскольку цикл должен проходить только с индексов 1 по 4.
<script type="text/javascript">
var ids = new Array();
var names = new Array();
var fields = 4;
function firstNames() {
var i;
var k;
for (i=1;i<=fields;i )
{
ids[i] = document.getElementById("field" i).value;
}
for (k=1; k<=fields; k )
{
FB.api('/' ids[k], function(response) {
names[k] = response.first_name;
alert(k ' test ' names[k]);
});
}
}
</script>
Кто-нибудь сталкивался с чем-то подобным? Любая помощь была бы высоко оценена.
Заранее спасибо.
Ответ №1:
Читать: Javascript, node.js и циклов for
Смотрите: Эксперимент № 7: Закрытие с новой областью видимости, устанавливающей новую переменную
URL: http://blog.mixu.net/2011/02/03/javascript-node-js-and-for-loops
У меня была та же проблема, что и у вас, т. е. FB.api получает индекс конечной итерации циклов FOR…
Пожалуйста, попробуйте это решение:
for (k=1; k<=fields; k )
{
// Closure with new scope establishing a new variable
(function() {
var index = k; // new variable
FB.api('/' ids[index], function(response) {
names[index] = response.first_name;
alert(index ' test ' names[index]);
});
}();
}
Обновление: Следует отметить, что оповещения в этом примере, вероятно, не будут выполняться последовательно, т. Е. вы можете получить 1,4,2,3 … все зависит от сетевой задержки каждого вызова API относительно порядка, в котором они выполняются…
Ответ №2:
Это был не тот же вызов Api, но я действительно столкнулся с чем-то похожим.
Вы должны понимать, что вызов facebook api является асинхронным. И, что самое главное, это медленно. Таким образом, javascript работает намного быстрее, и к моменту отправки первого ответа ваш цикл javascript for уже завершен. Вот почему все отправляется в k = 5, что является значением k после цикла.
Это происходит потому, что javascript не заставляет вас использовать конечную переменную в обработчике, как это делает java.
Итак, теперь вы понимаете, как это исправить? Хех, извините, я нашел грязное решение, когда у меня возникла такая проблема.
То, что я сделал, это обработал код непосредственно в теле функции (ответа) и не использовал промежуточные переменные. Итак, в качестве быстрого решения вы можете сделать то же самое и забыть о своем массиве имен или найти что-то получше.
Комментарии:
1. Ах, черт возьми, я боялся, что это будет что-то вроде этого. Думаю, сейчас мне придется поступить с этим некрасиво, а позже попытаться найти обходной путь. Спасибо за вашу помощь, Джоэл! 🙂
2. Я не думаю, что асинхронные вызовы api являются проблемой в отношении значения «k», равного «5»… Прочитайте этот комментарий Микито Такады: «технической основной причиной является стратегия разрешения области / оценки» — blog.mixu.net/2011/02/03/javascript-node-js-and-for-loops /…