Понимание области видимости переменной с помощью асинхронных операторов - PullRequest
1 голос
/ 18 января 2012

Когда я делаю следующее:

for (var CurrentRow=0;CurrentRow < qryMfg.RecordCount;CurrentRow++){
    console.log(qryMfg.MFGID[CurrentRow]);
    dbo.transaction(function(myTrans) {
        console.log(qryMfg.MFGID[CurrentRow]);
    });
}

Я получаю список MfgID нужным мне способом, за которым следует список неизвестных, потому что dbo.transaction выполняется асинхронно.

Как передать переменную в dbo.transaction?

Ответы [ 2 ]

4 голосов
/ 18 января 2012
for (var CurrentRow=0;CurrentRow < qryMfg.RecordCount;CurrentRow++) {
    console.log(qryMfg.MFGID[CurrentRow]);

    (function(row) {
        dbo.transaction(function(myTrans) {
            console.log(qryMfg.MFGID[row]);
        }); 
    })(CurrentRow);
}
4 голосов
/ 18 января 2012

Область видимости переменной создается в функциях, поэтому создайте функцию, которая возвращает обработчик ...

function create_handler( scoped_row ) {
    return function(myTrans) {
        console.log(qryMfg.MFGID[scoped_row]);
    };
}

... и вызывает его в цикле, передавая ему все, что вам нужно, в этом случае, CurrentRow ...

for (var CurrentRow=0;CurrentRow < qryMfg.RecordCount;CurrentRow++) {
    console.log(qryMfg.MFGID[CurrentRow]);
    dbo.transaction( create_handler(CurrentRow) );
}

Теперь каждый отдельный обработчик создается в той же уникальной области, которая была создана с помощью вызова в каждой итерации.

Поскольку CurrentRow было передано в эту область действия функции, каждый обработчик будет ссылаться на уникальное значение в своей области действия через параметр scoped_row.

Когда обработчик возвращается из функции, он будет передан в dbo.transaction.

Даже если он передан из функции, в которой он был создан, он сохранит свою исходную переменную область видимости и, следовательно, всегда будет иметь доступ к параметру scoped_row.


Вы также можете поместить всю функцию в функцию, если хотите.

function create_transaction( scoped_row ) {
    console.log(qryMfg.MFGID[scoped_row]);

    dbo.transaction( function(myTrans) {
        console.log(qryMfg.MFGID[scoped_row]);
    });
}

..., которая будет иметь тот же результат, если вы передадите ей CurrentRow ...

for (var CurrentRow=0;CurrentRow < qryMfg.RecordCount;CurrentRow++) {
    create_transaction( CurrentRow );
}
...