【问题标题】:"optional" generator inside a switch statement?switch 语句中的“可选”生成器?
【发布时间】:2017-02-03 23:47:25
【问题描述】:

是否可以在 switch 语句中使用生成器? 在函数中可能并不总是回传生成器?

在代码中:

function* getWebsite ($) {
  const contents = $('.selector-blah');
  if (contents) {
    const resp = yield http.getHTML({ url: contents.href });
    return resp.finalUrl;
  } else {
    return null;
  }
}

const selectorMappings = {
  name: '#name',
  starRating: getStarRating, // normal function
  website: getWebsite // generator function
}

yield processSelectors($, data, selectorMappings);
// <code> here is excuting before yield is complete above.

processSelectors 模块:

const _ = require('lodash');
const sanitizeText = require('./sanitizeText');

module.exports = function* processSelectors ($, data, selectors = {}, route = '') {
  const keys = Object.keys(selectors);
  for (let key of keys) {
    let path = route ? route + '.' + key : key;
    switch (selectors[key].constructor.name) {
      case 'String':
        _.set(data, path, sanitizeText($(selectors[key]).first().text()));
        break;
      case 'Function':
        _.set(data, path, selectors[key]($));
        break;
      case 'GeneratorFunction':
        var result = yield selectors[key]($);
        _.set(data, path, result);
        break;
      case 'Object':
        _.set(data, path, {});
        processSelectors($, data, selectors[key], path);
        break;
    }
  }
};

我确实在 forEach 中有开关,但为了避免嵌套函数而移出但没有帮助,还尝试使用 co 和 co.wrap 以及 Promise 的。

【问题讨论】:

  • 一个函数要么是生成器,要么不是。它不应该(不能)在运行时决定它想要成为什么。 调用者如何知道它决定是什么?
  • 你可以写一个从不产生的生成器函数,但你不应该写一个只偶尔返回一个生成器的函数。
  • yield processSelectors($, data, selectorMappings); 叫什么名字?
  • 它在另一个生成器函数中被调用,通过 co 调用。这一切都很好。我想我可以让它总是返回生成器,我已经尝试通过导出 co.wrap 函数。

标签: javascript ecmascript-6 generator es6-promise


【解决方案1】:

通过将整个东西变成一个生成器来实现这个工作:

yield processSelectors($, data, selectorMappings);

////////////////////////////////////////////////////////
//                       MODULE                       //
////////////////////////////////////////////////////////

const _ = require('lodash');
const sanitizeText = require('./sanitizeText');

module.exports = function* processSelectors ($, data, selectors = {}, route = '') {
  const keys = Object.keys(selectors);
  for (let key of keys) {
    let path = route ? route + '.' + key : key;
    switch (selectors[key].constructor.name) {
      case 'String':
        _.set(data, path, sanitizeText($(selectors[key]).first().text()));
        break;
      case 'Function':
        _.set(data, path, selectors[key]($));
        break;
      case 'GeneratorFunction':
        _.set(data, path, yield selectors[key]($));
        break;
      case 'Object':
        _.set(data, path, {});
        processSelectors($, data, selectors[key], path);
        break;
    }
  }
};

【讨论】:

    猜你喜欢
    • 2016-05-08
    • 1970-01-01
    • 2014-02-06
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多