2016-05-13 3 views
2

Я пытаюсь упростить, как я делаю вызовы AJAX с генераторами ES6. Тем не менее, я бегу на некоторые вопросы:Использование генераторов ES6 с XMLHttpRequest

let xhr = new XMLHttpRequest() 

function *statechange() { 
    yield xhr.readyState; 
} 

let gen = statechange(); 

xhr.open("GET", myUrl, true); 
xhr.onreadystatechange = function() {console.log(gen.next())}; 
xhr.send(); 

Просто краткое объяснение того, что я пытаюсь сделать: Я хочу, чтобы получить готовый-состояние каждого запроса на изменение состояния. Я регистрирую строку readyState на каждой итерации генератора. Но когда я запускаю этот код я получаю:

{value: 2, done: false} 
{value: undefined, done: true} 
{value: undefined, done: true} 

Который, на его поверхность выглядит хорошо, но если я старомодный XHR:

//... new XMLHttpRequest()... 
xhr.onreadystatechange = function() {console.log(xhr.readyState)} 

я получаю:

2 
3 
4 

Итак ... где я иду не так с моим использованием генераторов?


UPDATE:

Даже незнакомец, если я вхожу в readyState в генераторе:

//              HERE 
xhr.onreadystatechange = function() {console.log(xhr.readyState, gen.next())}; 

Я получаю это:

2, {value: 2, done: false} 
3, {value: undefined, done: true} 
4, {value: undefined, done: true} 

Таким образом, это значит, правильный readyState доступен, если next() метод называется. Я могу только догадываться, что оператор yield, который я использовал, регистрирует только один раз, поэтому генератор выделяет только один слот. Я понял, что с onreadystatechange вызывается более одного раза, будет выделено больше слотов. Как это исправить?

+0

'gen' достигает конца функции и, следовательно, является _done_ (также это на самом деле не упрощает XHR, вместо этого слушает нагрузку/ошибку, и вы можете записать их как обещания) –

ответ

3

Когда вы вызываете функцию генератора, она запускается до первого оператора yield, а затем приостанавливается до тех пор, пока не вызывается метод next. После этого он продолжает работать до тех пор, пока не будет выписан другой оператор yield, или функция или управления оставляет функцию. В последнем случае все вызовы метода next возвращают undefined.

То, что вы хотите это цикл, который проверяет readyState в XHR на каждой итерации:

function *statechange() { 
    while(true) { // loop forever 
    yield xhr.readyState; 
    } 
} 

Если вы знакомы с генераторами в Python, это точно так же.

Я собираюсь сделать второй комментарий @Paul S., что это не упрощает xhrs, и вы должны проверить обещания для этого.

Смежные вопросы