Как сделать простой цикл javascript в транспортире

for ( i = 0; i < 100; i++) {
         browser.manage().logs().get('browser').then(function(browserLog) {
                console.log(i);  
                });

    }

Я пытаюсь запустить это с помощью транспортира, но в консоли я печатаю сто раз 100. У меня есть некоторые функции, которые я пытаюсь реализовать с помощью зацикливания.Как я могу зациклить в транспортире?


person Rahul    schedule 12.11.2014    source источник
comment
По крайней мере, из вашего кода проблема не в транспортире, а в вашем незнании области видимости переменных JS и асинхронного кодирования. См. stackoverflow.com/q/750486/1169798 для решения.   -  person Sirko    schedule 12.11.2014


Ответы (1)


Это связано с тем, что все функции, которые вы передаете then, закрываются по переменной i, а не по значению этой переменной при создании функций. Поэтому позже, когда функции вызываются, все они видят значение i таким, какое оно есть затем, после завершения цикла (100).

Если вы хотите зафиксировать значение i таким, какое оно есть при создании функции, вы можете использовать Function#bind ES5:

for ( i = 0; i < 100; i++) {
    browser.manage().logs().get('browser').then(function(index, browserLog) {
        console.log(index);  
    }.bind(null, i));
}

bind возвращает новую функцию, которая при вызове вызовет исходную функцию с заданным значением this (в данном случае я использую null) и любыми аргументами, которые вы сопровождаете, за которыми следуют аргументы, переданные функции bind.

Другой подход - это функция строителя:

for ( i = 0; i < 100; i++) {
    browser.manage().logs().get('browser').then(buildHandler(i));
}
function buildHandler(index) {
    return function(browserLog) {
        console.log(index);
    };
}

Преимущество этого заключается в том, что вызывающая сторона может управлять this.

person T.J. Crowder    schedule 12.11.2014
comment
@Rahul: Неплохо, многие люди сначала этого не понимают. :-) Рад, что помог. - person T.J. Crowder; 12.11.2014