循环使用JavaScript生成器函数

时间:2016-09-30 18:13:39

标签: javascript

我正在尝试使用JavaScript生成器函数从数据库中获取数据。但每一步都取决于它之前的数据。我使用了Wes Bos的ES6.io课程中的一个例子,在那里,它做了类似的事情并且看起来像

function ajax(url) {
    fetch(url).then(data => data.json()).then(data => dataGen.next(data))
}

function* steps() {
    console.log('fetching beers');
    const beers = yield ajax('http://api.react.beer/v2/search?q=hops&type=beer');
    console.log(beers);

    console.log('fetching user');
    const user = yield ajax('https://api.github.com/users/[user]');
    console.log(user);

    console.log('fetching fat joe');
    const fatJoe = yield ajax('https://api.discogs.com/artists/51988');
    console.log(fatJoe);
}

const dataGen = steps();
dataGen.next(); // kick it off

这完美无缺。问题在于这取决于dataGen是否全球可用。我需要在一个函数中完成所有这些。如何在循环中调用dataGen但是从另一个函数调用?我正在寻找类似的东西:

function ajax(url) {
    fetch(url).then(data => data.json()).then(data => dataGen.next(data))
}

function* steps() {
    console.log('fetching beers');
    const beers = yield ajax('http://api.react.beer/v2/search?q=hops&type=beer');
    console.log(beers);

    console.log('fetching user');
    const user = yield ajax('https://api.github.com/users/[user]');
    console.log(user);

    console.log('fetching fat joe');
    const fatJoe = yield ajax('https://api.discogs.com/artists/51988');
    console.log(fatJoe);
}

function getInfo() {
    const dataGen = steps();
    for (const data of dataGen) {
        console.log(data);
    }
}
理想情况下,getInfo()调用能够启动生成器,并能够将数据从每个步骤传递到下一个步骤,以便正确填写数据。

有什么建议吗?我可以使用ES6功能或功能,但没有更高的功能。

这是浏览器控制台中的输出,当我尝试执行第二个选项时会发生什么,我喜欢这个选项:

enter image description here

1 个答案:

答案 0 :(得分:1)

这里棘手的部分是ajax函数不返回任何内容,如果确实如此,它不会立即返回数据。

所以,为了做你想要的,我们必须将promise逻辑移到我们的循环中。我们可以完全摆脱ajax()并直接使用fetch:

function* steps() {
    const beers = yield fetch('http://api.react.beer/v2/search?q=hops&type=beer');
    const user = yield fetch('https://api.github.com/users/wesbos');
    const fatJoe = yield fetch('https://api.discogs.com/artists/51988');
}

function getInfo() {
  const dataGen = steps();
  for(const promise of dataGen) {
    promise.then(data => data.json()).then(data => {
      console.log(data);
      dataGen.next(data);
    });
  }
}

getInfo();