【问题标题】:Correct way to continue on after a generator function生成器功能后继续的正确方法
【发布时间】:2014-06-01 13:40:23
【问题描述】:

我有以下生成器功能:

BulkLoader.prototype.load = function(password) {
  var self = this;

  return async(function * () {
    try {
      self.users = yield getJSON('/users');
      self.contacts = yield getJSON('/contacts');
      self.companies = yield getJSON('/companies');

      return self;
    } catch (err) {
      throw err;
    }
  });
};

asyc 方法看起来像这样,我从 Q 库中获取的:

export default function async(generatorFunc) {
  function continuer(verb, arg) {
    var result;
    try {
      result = generator[verb](arg);
    } catch (err) {
      return RSVP.Promise.reject(err);
    }
    if (result.done) {
      return result.value;
    } else {
      return RSVP.Promise.resolve(result.value).then(callback, errback);
    }
  }

  var generator = generatorFunc();
  var callback = continuer.bind(continuer, "next");
  var errback = continuer.bind(continuer, "throw");

  return callback();
}

我的调用代码如下所示:

var bulkLoader = new GeneratorBulkLoader();

bulkLoader.load()
  .then(render)
  .catch(errorHandler);

在调用生成器函数后必须使用 Promise 似乎有点奇怪。

其他人在使用生成器时如何处理他们的调用代码?

【问题讨论】:

  • 那么您希望如何使用生成器函数?
  • 为什么在包含 Q 中使用 RSVP 的代码时将其标记为 es6-promise

标签: javascript generator promise


【解决方案1】:

在调用生成器函数后必须使用 Promise 似乎有点奇怪。

为什么? API 仍然是一个承诺。它是否在内部使用了生成器并没有什么不同。

其他人在使用生成器时如何处理他们的调用代码?

您也可以随时使用生成器来为您的调用代码添加糖分:

async(function* () {
    var bulkLoader = new GeneratorBulkLoader();

    try {
        yield render(yield bulkLoader.load())
    } catch(e) {
        errorHandler(e);
    }
});

【讨论】:

  • 具有讽刺意味的是,带有 promise 的调用代码明显更清晰(实际上,通过简单的 return Promise.all(...),被调用代码也会更清晰,性能也更高)
猜你喜欢
  • 2014-02-26
  • 1970-01-01
  • 2019-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多