2016-04-27 2 views
2

Я прочитал статью Дэвида Уолша об использовании генераторов в задачах async (https://davidwalsh.name/async-generators), и я хотел сделать то же самое. Вот мой код:ES6: Использование генератора при асинхронных вызовах

function request(time) { 
    let rand = Math.random()*10; 
    console.log(`rand is ${rand}`); 
    setTimeout(function(rand){ 
     it.next(rand) 
    }, time); 
} 

function *main() { 
    let result1 = yield request(5); 
    result1 = parseInt(result1); 
    let result2 = yield request(result1); 

    console.log(`result1 is ${result1} and result2 is ${result2}`); 
} 

let it = main(); 
it.next(); 

, но в консоли я вижу

rand is 6.367766260304355 
rand is 0.3009188563265597 
result1 is NaN and result2 is undefined 

Насколько я могу видеть, когда скрипт достигает пусть ранд = Math.random() * 10 для первого значения времени сохраненный в rand, но затем он переходит в setTimeout, но не входит в него, но достигает it.next() в конце скрипта, а затем возвращается к внутреннему пространству setTimeout, но на этот раз rand не определен. Почему? Как я могу сохранить значение rand и передать его result1?

Edit: OK, когда я редактировал

function request(time) { 
    setTimeout(function(){ 
     let rand = Math.random()*10; 
     console.log(`rand is ${rand}`); 
     it.next(rand) 
    }, time); 
} 

он работает отлично. Кажется, я не могу передать значение setTimeout ... Почему?

ответ

3

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

Эти аргументы необходимо передать setTimeoutitself.

var timeoutID = window.setTimeout(func, [delay, param1, param2, ...]); 


function request(time) { 
    let rand = Math.random()*10; 
    console.log(`rand is ${rand}`); 
    setTimeout(function(rand){ 
     it.next(rand) 
    }, time, rand); 
} 

Но это не обязательно в вашем случае. У вас есть rand доступный внутри внутренней функции.

function request(time) { 
    let rand = Math.random()*10; 
    console.log(`rand is ${rand}`); 
    setTimeout(function(){ 
     it.next(rand); 
    }, time); 
} 
1

У вас есть два rand переменных в коде:

let rand = Math.random()*10; 
// ^^^^ 
… 
setTimeout(function(rand) { 
//     ^^^^ 
    … 
}, time); 

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

Просто не объявляйте этот параметр, а внешний rand будет доступен в обратном вызове путем закрытия.