I am using Koa and Bluebird and is trying out coroutines. I find that the below gives me an error. But if I replace yield initRouters()
with the contents of initRouters()
it works. Why is that?
'use strict';
const fs = require('fs');
const Promise = require('bluebird');
const readdir = Promise.promisify(fs.readdir);
let app = require('koa')();
let initRouters = function *() {
const routerDir = `${__dirname}/routers`;
let routerFiles = yield readdir(routerDir);
return Promise.map(routerFiles, function *(file) {
var router = require(`${routerDir}/${file}`);
app
.use(router.routes())
.use(router.allowedMethods());
});
}
Promise.coroutine(function *() {
yield initRouters();
const PORT = process.env.PORT || 8000;
app.listen(PORT);
console.log(`Server listening on ${PORT}`);
})();
The error I get is
Unhandled rejection TypeError: A value [object Generator] was yielded that could not be treated as a promise
See
From coroutine:
at Function.Promise.coroutine (/home/jiewmeng/Dropbox/expenses-app/node_modules/bluebird/js/release/generators.js:176:17)
at Object.<anonymous> (/home/jiewmeng/Dropbox/expenses-app/src/app.js:21:9)
at PromiseSpawn._continue (/home/jiewmeng/Dropbox/expenses-app/node_modules/bluebird/js/release/generators.js:145:21)
at PromiseSpawn._promiseFulfilled (/home/jiewmeng/Dropbox/expenses-app/node_modules/bluebird/js/release/generators.js:92:10)
at /home/jiewmeng/Dropbox/expenses-app/node_modules/bluebird/js/release/generators.js:183:15
at Object.<anonymous> (/home/jiewmeng/Dropbox/expenses-app/src/app.js:27:3)
at Module._pile (module.js:413:34)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
at startup (node.js:141:18)
at node.js:933:3
I am using Koa and Bluebird and is trying out coroutines. I find that the below gives me an error. But if I replace yield initRouters()
with the contents of initRouters()
it works. Why is that?
'use strict';
const fs = require('fs');
const Promise = require('bluebird');
const readdir = Promise.promisify(fs.readdir);
let app = require('koa')();
let initRouters = function *() {
const routerDir = `${__dirname}/routers`;
let routerFiles = yield readdir(routerDir);
return Promise.map(routerFiles, function *(file) {
var router = require(`${routerDir}/${file}`);
app
.use(router.routes())
.use(router.allowedMethods());
});
}
Promise.coroutine(function *() {
yield initRouters();
const PORT = process.env.PORT || 8000;
app.listen(PORT);
console.log(`Server listening on ${PORT}`);
})();
The error I get is
Unhandled rejection TypeError: A value [object Generator] was yielded that could not be treated as a promise
See http://goo.gl/MqrFmX
From coroutine:
at Function.Promise.coroutine (/home/jiewmeng/Dropbox/expenses-app/node_modules/bluebird/js/release/generators.js:176:17)
at Object.<anonymous> (/home/jiewmeng/Dropbox/expenses-app/src/app.js:21:9)
at PromiseSpawn._continue (/home/jiewmeng/Dropbox/expenses-app/node_modules/bluebird/js/release/generators.js:145:21)
at PromiseSpawn._promiseFulfilled (/home/jiewmeng/Dropbox/expenses-app/node_modules/bluebird/js/release/generators.js:92:10)
at /home/jiewmeng/Dropbox/expenses-app/node_modules/bluebird/js/release/generators.js:183:15
at Object.<anonymous> (/home/jiewmeng/Dropbox/expenses-app/src/app.js:27:3)
at Module._pile (module.js:413:34)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
at startup (node.js:141:18)
at node.js:933:3
Share
Improve this question
asked Mar 12, 2016 at 4:24
Jiew MengJiew Meng
88.6k192 gold badges529 silver badges833 bronze badges
2
-
I think you need to wrap your
initRouters
generator function in Promise.coroutine as well – laggingreflex Commented Mar 12, 2016 at 10:15 -
In
initRouters
tryyield
ing thePromise.map()
call instead of returning it. – mikefrey Commented Mar 16, 2016 at 16:35
2 Answers
Reset to default 6You have reach an egg/chicken problem.
Promise.coroutine
let's you yield a promise:
Returns a function that can use yield to yield promises.
The problem here is that you trying to yield a generator function, not a promise. This results in the error:
Unhandled rejection TypeError: A value [object Generator] was yielded that could not be treated as a promise
Why?
Well, the generator function returns a promise, but it's only a promise when you yield it. And because you can't yield a generator function, you never get the value (the promise).
You can (and should) use coroutine
and yield initRouters();
. BUT, that initRouters()
should be a normal function that returns a promise, not a generator function.
As a side note, you don't need Promise.map()
because everything you do inside the .map
is synchronous, so you can perfectly do:
let initRouters = function() {
const routerDir = `${__dirname}/routers`;
return readdir(routerDir).then(function (files) {
files.map(function (file) {
var router = require(`${routerDir}/${file}`);
app
.use(router.routes())
.use(router.allowedMethods());
})
})
}
Here you are returning a promise that resolves when you yield it. But as you see, you are returning already a promise, that's why Promise.coroutine
doesn't give you any error. In the case of the generator, you are not returning a promise.
initRouters()
returns a generator. You can't yield
that to Promise.coroutine
, which only allows you to yield promises (as the error clearly indicates).
You either need to wrap initRouters
in Promise.coroutine
itself, or use
yield* initRouters();
so that all promises from the generator are yielded and not the generator itself. Notice that the co
library does allow such quirks, in contrast to Bluebird.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745375575a4624983.html
评论列表(0条)