2015-10-12 26 views
0

我最近學到了一點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 
     }; 
    } 
    } 
} 
+2

發電機功能在這裏呢?如果你不使用發電機,你會得到什麼?什麼是'_apps.count'應該返回? –

回答

1

興亞,這是基於合作,任何異步操作必須yield承諾一路攀升到興亞。您也可以生成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 
     }; 
    } 
    } 
}