Сохранение ответа вызова FB.api на массив с циклом for с помощью Javascript

#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 /…