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


当前回答

举个简单的例子:

const strArr = ["red", "green", "blue", "black"];

const strGen = function*() {
    for(let str of strArr) {
        yield str;
    }
};

let gen = strGen();

for (let i = 0; i < 5; i++) {
    console.log(gen.next())
}

//prints: {value: "red", done: false} -> 5 times with different colors, if you try it again as below:

console.log(gen.next());

//prints: {value: undefined, done: true}

其他回答

不要忘记使用非常有用的“x of generator”语法来遍历生成器。根本不需要使用next()函数。

function* square(x){
    for(i=0;i<100;i++){
        x = x * 2;
        yield x;        
    }   
}

var gen = square(2);
for(x of gen){
   console.log(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之前,您需要了解生成器。生成器是使用函数*语法创建的。Generator函数不执行代码,而是返回一种称为Generator的迭代器。当使用下一个方法给出一个值时,生成器函数将继续执行,直到遇到yield关键字。使用yield返回一个包含两个值的对象,一个是value,另一个是done(布尔值)。该值可以是数组、对象等。

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());

异步javascript调用之间的依赖关系。

另一个关于如何使用yield的好例子。

函数请求(url) { Axios.get (url).then((response) => { it.next(响应); }) } 函数* main() { Const result1 = yield request('http://some.api.com'); Const result2 = yield request('http://some.otherapi?Id =' + result1。id); console.log('您的响应是:' + result2.value); } Var it = main(); it.next ()