用于执行javascript生成器的惯用模式

用于执行javascript生成器的惯用模式,javascript,ecmascript-6,generator,Javascript,Ecmascript 6,Generator,很明显,我对发电机有些不了解 我有一个生成器,它使用fetch function* log(logObject) { const params = { method: 'POST', body: JSON.stringify(logObject), }; const response = yield fetch('/log', params); if (response.ok) { const json = response.json(); r

很明显,我对发电机有些不了解

我有一个生成器,它使用
fetch

function* log(logObject) {
  const params = {
    method: 'POST',
      body: JSON.stringify(logObject),
  };
  const response = yield fetch('/log', params);
  if (response.ok) {
    const json = response.json();
    return { json };
  }
  return { response };
}
我想从一个常规函数执行这个生成器

function doStuff(stuff) {
  if (hasIssues(stuff)) {
    const logGen = log({ data: { message: 'error log' } });
    return logGen.next().value;

    // but what if i add more yields to `log` in the future?  
    // i'll then need to modify this and every other function that calls `log` to have 2 calls to next()...
    // is there a way to just say, 'do all the things'?

  }
  ...
}
如何使我的代码足够灵活,以使生成器函数中的附加
生成
,不需要我修改生成器的每次使用以包含对
next()
的附加调用

我想我可以用一个空块来表示…of

for (let x of log({ data: { message: 'error log' } })) {}

但是有一个空的块循环似乎是一种代码味道……有更好的方法吗?

您真的想使用ES8
async
/
wait
来处理使用代码的异步承诺。下降发生器

async function log(logObject) {
  const params = {
    method: 'POST',
      body: JSON.stringify(logObject),
  };
  const response = await fetch('/log', params);
  if (response.ok) {
    const json = await response.json(); // don't forget to wait for the full body
    return { json };
  }
  return { response }; // are you sure you don't want to throw an error?
}

async function doStuff(stuff) { /*
^^^^^ this becomes asynchronous as well */
  if (hasIssues(stuff)) {
    const responseOrJson = await log({ data: { message: 'error log' } });
    …
  }
  …
}

您确实希望使用ES8
async
/
wait
来处理使用代码的异步承诺。下降发生器

async function log(logObject) {
  const params = {
    method: 'POST',
      body: JSON.stringify(logObject),
  };
  const response = await fetch('/log', params);
  if (response.ok) {
    const json = await response.json(); // don't forget to wait for the full body
    return { json };
  }
  return { response }; // are you sure you don't want to throw an error?
}

async function doStuff(stuff) { /*
^^^^^ this becomes asynchronous as well */
  if (hasIssues(stuff)) {
    const responseOrJson = await log({ data: { message: 'error log' } });
    …
  }
  …
}

如果你不想使用它,为什么你的生成器
会产生
任何东西?看起来你在滥用生成器,实际上想使用
async
/
await
。我确实在使用它,只是试图简化示例…@Bergi:你能用async/await举一个上面的例子吗?我没有想到这一点,我希望有一个更好的模式。我不知道您在哪里使用
获取(…)
结果,您
产生了
ed。我怀疑您发布的代码甚至不起作用。也许你应该给我们看一个完整的例子如果你不想使用,为什么你的生成器
会产生
任何东西?看起来你在滥用生成器,实际上想使用
async
/
await
。我确实在使用它,只是想简化这个例子…@Bergi:你能用async/await举一个上面的例子吗?我没有想到这一点,我希望有一个更好的模式。我不知道您在哪里使用
获取(…)
结果,您
产生了
ed。我怀疑您发布的代码甚至不起作用。也许你应该给我们看一个完整的例子