我一直在研究Promises and Generators,但是我陷入了下面的脚本中:
function getFile(file) {
return new Promise(function (resolve) {
fakeAjax(file, resolve);
});
}
function* getFiles() {
var p1 = getFile('file1');
var p2 = getFile('file2');
var p3 = getFile('file3');
output(yield p1);
output(yield p2);
output(yield p3);
}
function runner(gen) {
var g = gen();
function run(val) {
val || undefined;
var next = g.next(val);
if(!next.done && !next.value !== undefined) {
next.value
.then(function(v) {
run(v);
});
}
}
run();
}
runner(getFiles);
我要弄清楚的是,当我获得getFiles的第一个收益时会发生什么?为什么这段代码行得通,我不明白。
* EDIT:输出只是函数中的console.log包装。 fakeAjax函数根据请求的“文件”从对象返回文本。
答案 0 :(得分:1)
我要弄清楚的是,当我获得getFiles的第一个收益时会发生什么?为什么这段代码行得通,我不明白。
yield
做三件事:
next()
的调用方将在value
属性中接收的值。在这种情况下,这就是您的承诺。next()
中。这将是您作为参数传递给next()
的文件名。 yield
就像一条双向管道,既接受值又传递值。
在您的代码的第一个yield
中,它将返回带有诺言并暂停的对象,但是此时它不将任何内容记录到控制台中-yield
可以暂停中间表达式。当您再次调用next()
时,它将完成console.log,然后移至下一个yield
。这可能会造成一些混乱,因为通常会再有next
的调用yields
。例如,在此代码中`next被调用了四次,这就是为什么获得最后一个console.log的原因。
这是一个MCVE,我认为是您的示例中未定义的函数:
function getFile(file) {
return new Promise(resolve => setTimeout(() => resolve(file), 1000))
}
function* getFiles() {
var p1 = getFile('file1');
var p2 = getFile('file2');
var p3 = getFile('file3');
console.log(yield p1); // return promise, then pause, then log value passed to next()
console.log(yield p2);
console.log(yield p3);
}
function runner(gen) {
var g = gen();
function run(val) {
var next = g.next(val);
if(!next.done && !next.value !== undefined) {
next.value
.then(function(v) {
run(v);
});
}
}
run();
}
runner(getFiles);