我听说过JavaScript中的“yield”关键字,但我发现关于它的文档非常糟糕。有人能给我解释一下(或者推荐一个解释它的网站)它的用法和用途吗?


当前回答

迟回答,也许现在每个人都知道收益率,但一些更好的文件已经出现。

将James Long的《Javascript的未来:生成器》中的一个例子改编为官方的Harmony标准:

function * foo(x) {
    while (true) {
        x = x * 2;
        yield x;
    }
}

当你调用foo时,你会得到一个Generator对象,它有一个next 方法。”

var g = foo(2);
g.next(); // -> 4
g.next(); // -> 8
g.next(); // -> 16

收益率有点像回报,你会得到一些回报。Return x返回x的值,但yield x返回一个函数,它为您提供了一个迭代到下一个值的方法。如果您有一个潜在的内存密集型过程,您可能希望在迭代期间中断这个过程,那么这个方法很有用。

其他回答

Yield关键字在javaScript函数使它生成器,

什么是JavaScript生成器?

生成器是产生一系列结果而不是单个值的函数,即您生成一系列值

这意味着生成器可以帮助我们与帮助迭代器异步工作,哦,hack迭代器是什么?真的吗?

迭代器意味着我们可以一次访问一个项

从哪里迭代器可以帮助我们一次访问第一项? 它帮助我们通过生成器函数访问项目,生成器函数中我们使用yield关键字,yield关键字帮助我们暂停和恢复函数的执行。

这里有一个简单的例子:

function *getMeDrink() {

    let question1 = yield 'soda or beer'; // execution will pause here because of yield
       
    if (question1 == 'soda') {
        return 'here you get your soda';
    }

    if (question1 == 'beer') {

        let question2 = yield 'What\'s your age'; // execution will pause here because of yield

        if (question2 > 18) {
            return "ok you are eligible for it";
        } else {
            return "Shhhh!!!!";
        }
    }
}

let _getMeDrink = getMeDrink(); // initialize it

_getMeDrink.next().value; // "soda or beer"

_getMeDrink.next('beer').value; // "What's your age"

_getMeDrink.next('20').value; // "ok you are eligible for it"

_getMeDrink.next().value; // undefined

让我简单地解释一下发生了什么

你注意到在每个yield关键字处执行被暂停,我们可以通过迭代器.next()访问第一个yield

它一次迭代到所有yield关键字,然后当没有更多的yield关键字时返回undefined,简单地说,你可以说yield关键字是断点,函数每次暂停,只有在使用迭代器调用它时才恢复,对于我们的例子:_getMeDrink.next()这是一个迭代器的例子,它帮助我们访问函数中的每个断点。

生成器示例: 异步/等待

如果你看到async/await的实现,你会看到生成器函数和承诺被用来使async/await工作,请指出任何建议,欢迎。

给出一个完整的答案:yield的工作原理类似于return,但在发电机中。

对于通常给出的例子,其工作原理如下:

function *squareGen(x) {
    var i;
    for (i = 0; i < x; i++) {
        yield i*i;
    }
}

var gen = squareGen(3);

console.log(gen.next().value); // prints 0
console.log(gen.next().value); // prints 1
console.log(gen.next().value); // prints 4

但是yield关键字还有第二个用途。它可以用来向生成器发送值。

为了澄清,举个小例子:

function *sendStuff() {
    y = yield (0);
    yield y*y;
}

var gen = sendStuff();

console.log(gen.next().value); // prints 0
console.log(gen.next(2).value); // prints 4

它的工作原理是,将值2赋给y,在它停止在第一个yield(返回0)后将其发送给生成器。

这使我们能够看到一些非常时髦的东西。(查协程)

Yield还可以使用协程框架来消除回调地狱。

function start(routine, data) {
    result = routine.next(data);
    if(!result.done) {
        result.value(function(err, data) {
            if(err) routine.throw(err); // continue next iteration of routine with an exception
            else start(routine, data);  // continue next iteration of routine normally
        });
    }
}

// with nodejs as 'node --harmony'
fs = require('fs');
function read(path) {
    return function(callback) { fs.readFile(path, {encoding:'utf8'}, callback); };
}

function* routine() {
    text = yield read('/path/to/some/file.txt');
    console.log(text);
}

// with mdn javascript 1.7
http.get = function(url) {
    return function(callback) { 
        // make xhr request object, 
        // use callback(null, resonseText) on status 200,
        // or callback(responseText) on status 500
    };
};

function* routine() {
    text = yield http.get('/path/to/some/file.txt');
    console.log(text);
}

// invoked as.., on both mdn and nodejs

start(routine());

迟回答,也许现在每个人都知道收益率,但一些更好的文件已经出现。

将James Long的《Javascript的未来:生成器》中的一个例子改编为官方的Harmony标准:

function * foo(x) {
    while (true) {
        x = x * 2;
        yield x;
    }
}

当你调用foo时,你会得到一个Generator对象,它有一个next 方法。”

var g = foo(2);
g.next(); // -> 4
g.next(); // -> 8
g.next(); // -> 16

收益率有点像回报,你会得到一些回报。Return x返回x的值,但yield x返回一个函数,它为您提供了一个迭代到下一个值的方法。如果您有一个潜在的内存密集型过程,您可能希望在迭代期间中断这个过程,那么这个方法很有用。

在我看来,MDN文档非常好。

The function containing the yield keyword is a generator. When you call it, its formal parameters are bound to actual arguments, but its body isn't actually evaluated. Instead, a generator-iterator is returned. Each call to the generator-iterator's next() method performs another pass through the iterative algorithm. Each step's value is the value specified by the yield keyword. Think of yield as the generator-iterator version of return, indicating the boundary between each iteration of the algorithm. Each time you call next(), the generator code resumes from the statement following the yield.