Сообщение от melky
|
да, я сейчас хотел написать функцию факториала на co.. в общем, мне нужна подготовка)
|
Все эти
co
и
Q.async
на самом деле ничего сложного не делают, а просто автоматически выстраивают такую штуку:
gen.next().value.then(function (value1) {
gen.next(value1).value.then(function (value2) {
gen.next(value2).value.then(function (value3) {
gen.next(value3)...
});
})
});
Вот рабочий пример для понимания:
function asyncGet1(value) {
return new Promise(function (resolve) {
setImmediate(resolve, value);
});
}
function asyncGet2(value) {
return new Promise(function (resolve) {
setImmediate(resolve, value + 1);
});
}
function asyncGet3(value) {
return new Promise(function (resolve) {
setImmediate(resolve, value * 2);
});
}
function * genFunc() {
var x = yield asyncGet1(1);
console.log('x = ' + x); // x = 1
var y = yield asyncGet2(x);
console.log('y = ' + y); // y = 2
var z = yield asyncGet3(y);
console.log('z = ' + z); // z = 4
}
//вместо co или Q.async:
var gen = genFunc();
gen.next().value.then(function (x) {
gen.next(x).value.then(function (y) {
gen.next(y).value.then(function (z) {
gen.next(z);
});
})
});
yield
никакой асинхронностью не занимается, он просто останавливает выполнение генератора до следующего вызова
next
.
Когда пишешь генератор, можно представлять, что
co
в паре с
yield
разбивают
genFunc
на вот такие «подфункции»:
function next1() {
asyncGet1(1).then(next2);
}
function next2(value) {
x = value;
asyncGet2(x).then(next3);
}
function next3(value) {
y = value;
asyncGet3(y).then(next4);
}
function next4(value) {
z = value;
}
Здесь специально расписал через value, чтобы воспринималось, как promise value.
Кстати, в ES7 возможно будет реализация этого паттерна на уровне языка. Будут введены инструкции
async
(вместо
co
,
Q.async
) и
await
(вместо
yield
), и генераторы для это не нужны будут:
async function func() {
var x = await asyncGet1(1);
var y = await asyncGet2(x);
var z = await asyncGet3(y);
}