发电机功能无法产生适当的值

问题描述 投票:0回答:1

我最近学到了一些ES6并使用在io.js上运行的koa.js开始了我的新项目。

在下面的代码中,我试图检查是否已经有另一个项目具有相同的url slug

counter.next().value的值总是返回一个函数,因此函数_slugExists总是返回true

'use strict';

let _ = require('lodash');
let config = require('../../config');

let monk = require('monk');
let wrap = require('co-monk');
let db = monk(config.db);

let _apps = wrap(db.get('apps'));

function _validateApp(app) {
  let slug = app.slug.trim();

  if (!app.name.trim()) {
    throw new Error('App name was not specified.');
  }

  if (!slug) {
    throw new Error('App URL was not specified.');
  }

  if (_slugExists(slug)) {
    throw new Error('Another app with the same URL already exists.');
  }
}

function* _count(filter) {
  yield _apps.count(filter);
}

function _slugExists(slug) {
  let counter = _count({
    slug: slug
  });

  return counter.next().value !== 0;
}

module.exports = {
  list: function*(next) {
    this.status = 200;
    this.body = yield _apps.find({});
  },
  create: function*(next) {
    try {
      let app = this.request.body;
      _validateApp(app);

      this.status = 201;
      this.body = {
        id: yield _apps.insert({
          name: app.name.trim(),
          slug: app.slug.trim(),
          created_at: new Date()
        })
      };
    } catch (error) {
      console.log(`[ERROR] ${error.message}`);

      this.status = 500;
      this.body = {
        error: error.message
      };
    }
  }
}
javascript ecmascript-6 koa iojs
1个回答
2
投票

在koa,这是基于co,任何异步操作必须yield承诺一直到koa。你也可以使用yield发生器,但不能使用迭代器。特别重要的是确保嵌套的异步操作不会挂起:

function* middleware(next) {
  yield Promise.resolve(0); // Yielding a promise. Good.
  yield (function() { return Promise.resolve(0); })(); // Also yielding a promise. Good.

  yield gen(4); // Yielding iterator. NOT GOOD!
  yield gen; // Yielding generator. Good, but no arg.
  yield* gen(4); // Delegating iterator. Good!

  hangingNested(); // Not yielding anything, async is lost. NOT GOOD!
  yield properNested; // Yielding generator with nested delegate, good!
}

function* gen(arg) {
  yield Promise.resolve(1);
  yield Promise.resolve(2);
  yield Promise.resolve(3);
  return arg;
}

function hangingNested() { // not a generator, nothing is yielded outside.
  gen(4); // iterator is lost.
}

function* properNested() {
  yield* gen(4); // Delegating iterator.
}

考虑到这一点,您可以通过多种方式修复代码,例如:

function* _validateApp(app) {
  let slug = app.slug.trim();

  if (!app.name.trim()) {
    throw new Error('App name was not specified.');
  }

  if (!slug) {
    throw new Error('App URL was not specified.');
  }

  if (yield* _slugExists(slug)) {
    throw new Error('Another app with the same URL already exists.');
  }
}

function* _count(filter) {
  return yield _apps.count(filter);
}

function* _slugExists(slug) {
  let counter = yield* _count({
    slug: slug
  });

  return counter !== 0;
}

module.exports = {
  list: function*(next) {
    this.status = 200;
    this.body = yield _apps.find({});
  },
  create: function*(next) {
    try {
      let app = this.request.body;
      yield* _validateApp(app);

      this.status = 201;
      this.body = {
        id: yield _apps.insert({
          name: app.name.trim(),
          slug: app.slug.trim(),
          created_at: new Date()
        })
      };
    } catch (error) {
      console.log(`[ERROR] ${error.message}`);

      this.status = 500;
      this.body = {
        error: error.message
      };
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.