简体   繁体   English

发电机+承诺说明

[英]Generators + Promises explanation

I've been studying Promises and Generators but I got stuck in the script below: 我一直在研究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);

What I'm trying to figure it out is what happens when I get to the first yield on getFiles? 我要弄清楚的是,当我在getFiles上获得第一笔收益时会发生什么? Why does this code work, I don't get it. 为什么此代码有效,但我不明白。

*EDIT: output is simply a console.log wrappend in a function. *编辑:输出只是函数中的console.log包装。 The fakeAjax function returns a text from an object based on the 'file' requested. fakeAjax函数根据请求的“文件”从对象返回文本。

What I'm trying to figure it out is what happens when I get to the first yield on getFiles? 我要弄清楚的是,当我在getFiles上获得第一笔收益时会发生什么? Why does this code work, I don't get it. 为什么此代码有效,但我不明白。

yield does three things: yield做三件事:

  1. It pause the execution of the generator function 暂停生成器功能的执行
  2. It defines the value the caller of next() will receive in the value property. 它定义了next()的调用者将在value属性中接收的value In this case, that's the promises you made. 在这种情况下,这就是您的承诺。
  3. It optionally acts as an expression with the value passed into next() . 可以选择将其用作表达式,并将值传递给next() That will be the file name you passed as a argument to next() . 那将是您作为参数传递给next()的文件名。

yield is like a two-way conduit, both accepting values and passing values. yield就像一条双向管道,既接受价值又传递价值。

In your code at the first yield it will return the object with the promise and pause, but it doesn't log anything to the console at this point — yield can pause mid-expression. 在您的代码中,第一个yield会返回带有promise和pause的对象,但是此时它不会将任何内容记录到控制台中yield可以使中间表达式暂停。 When you call next() again it will finish the console.log and then move to the next yield . 再次调用next()时,它将完成console.log,然后移至下一个yield It can be a little confusing because there is usually one more call to next that there are yields . 这可能会造成一些混乱,因为通常还会再有一个电话通知next yields For example in this code `next is called four times and that's why you get the last console.log. 例如,在此代码中`next被调用了四次,这就是为什么您得到最后一个console.log的原因。

Here's an MCVE that I assume approximates the undefined functions in your example: 这是我认为您的示例中的未定义函数近似的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); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM