在生成器完成时,将连续生成的值作为数组返回

时间:2017-06-03 17:55:47

标签: javascript ecmascript-6 generator

我想知道在生成器完成时是否可以将连续生成的值作为数组返回。这是我到目前为止所尝试的,我在生成器的末尾添加一个return语句并尝试对输出进行解构:

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

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

  const wes = yield ajax('https://api.github.com/users/wesbos');

  const fatJoe = yield ajax('https://api.discogs.com/artists/51988');

  return [beers, wes, fatJoe]
}

const dataGen = steps();
const [beers, wes, fatJoe] = dataGen.next(); // kick it off

但是,没有返回任何值:

Uncaught ReferenceError: beers is not defined
Uncaught ReferenceError: wes is not defined
Uncaught ReferenceError: fatJoe is not defined

2 个答案:

答案 0 :(得分:1)

如果正确解释问题,您可以使用yield*,将steps()来电传递给Promise.all().then()



<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Generators</title>
</head>
<body>
<script>

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

  function* steps() {
    yield* [
             ajax('data:application/json,[1]')
             , ajax('data:application/json,[2]')
             , ajax('data:application/json,[3]')
           ];
  }

  // kick it off
  Promise.all(steps())
  .then(([beers, wes, fatJoe]) => 
    console.log(beers, wes, fatJoe)
  )
</script>
</body>
</html>
&#13;
&#13;
&#13;

Promise.all()没有生成器功能

&#13;
&#13;
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Generators</title>
</head>
<body>
<script>

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

  function steps() {
    return [
             ajax('data:application/json,[1]')
             , ajax('data:application/json,[2]')
             , ajax('data:application/json,[3]')
           ];
  }

  // kick it off
  Promise.all(steps())
  .then(([beers, wes, fatJoe]) => 
    console.log(beers, wes, fatJoe)
  )
</script>
</body>
</html>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

停止使用生成器替代async / await。如果您想这样做,则需要使用适当的异步运行器,例如co库或Bluebird.coroutine。但他们的时代已经过去了,async / await在最近的浏览器中很容易获得(无论如何都是在转发器中)!

function ajax(url) {
  return fetch(url).then(data => data.json());
//^^^^^^
}

async function steps() {
  const beers = await ajax('http://api.react.beer/v2/search?q=hops&type=beer');
  const wes = await ajax('https://api.github.com/users/wesbos');
  const fatJoe = await ajax('https://api.discogs.com/artists/51988');

  return [beers, wes, fatJoe];
}

const dataPromise = steps(); // kick it off
dataPromise.then(([beers, wes, fatJoe]) => {
  console.log(…); // use results here
});

(或者在另一个异步函数中等待dataPromise