产生了一个不能被视为承诺的价值
A value was yielded that could not be treated as a promise
我正在使用 Koa 和 Bluebird,并且正在尝试协程。我发现下面给了我一个错误。但是,如果我将 yield initRouters()
替换为 initRouters()
的内容,它就会起作用。这是为什么?
'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}`);
})();
我得到的错误是
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._compile (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
您遇到了 egg/chicken 个问题。
Promise.coroutine
许你一个诺言:
Returns a function that can use yield to yield promises.
这里的问题是你试图产生一个生成器函数,而不是一个承诺。这导致错误:
Unhandled rejection TypeError: A value [object Generator] was yielded that could not be treated as a promise
为什么?
好吧,生成器函数 returns 是一个承诺,但只有当你 yield 时它才是一个承诺。因为你不能产生生成器函数,所以你永远不会得到值(承诺)。
您可以(并且应该)使用 coroutine
和 yield initRouters();
。 但是,initRouters()
应该是一个正常的函数,returns 一个 promise,而不是生成器函数。
附带说明一下,您不需要 Promise.map()
因为您在 .map
中所做的一切都是同步的,因此您可以完美地做到:
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());
})
})
}
在这里你返回一个承诺,当你放弃它时解决。但是正如您所见,您已经返回了一个承诺,这就是 Promise.coroutine
不会给您任何错误的原因。对于生成器,您没有返回承诺。
initRouters()
returns 一台发电机。你不能 yield
到 Promise.coroutine
,这只允许你产生承诺(正如错误清楚地表明的那样)。
您要么需要将 initRouters
包装在 Promise.coroutine
中,要么使用
yield* initRouters();
以便产生来自生成器的所有承诺,而不是生成器本身。请注意,与 Bluebird 相比,co
库确实允许这种怪癖。
我正在使用 Koa 和 Bluebird,并且正在尝试协程。我发现下面给了我一个错误。但是,如果我将 yield initRouters()
替换为 initRouters()
的内容,它就会起作用。这是为什么?
'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}`);
})();
我得到的错误是
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._compile (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
您遇到了 egg/chicken 个问题。
Promise.coroutine
许你一个诺言:
Returns a function that can use yield to yield promises.
这里的问题是你试图产生一个生成器函数,而不是一个承诺。这导致错误:
Unhandled rejection TypeError: A value [object Generator] was yielded that could not be treated as a promise
为什么?
好吧,生成器函数 returns 是一个承诺,但只有当你 yield 时它才是一个承诺。因为你不能产生生成器函数,所以你永远不会得到值(承诺)。
您可以(并且应该)使用 coroutine
和 yield initRouters();
。 但是,initRouters()
应该是一个正常的函数,returns 一个 promise,而不是生成器函数。
附带说明一下,您不需要 Promise.map()
因为您在 .map
中所做的一切都是同步的,因此您可以完美地做到:
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());
})
})
}
在这里你返回一个承诺,当你放弃它时解决。但是正如您所见,您已经返回了一个承诺,这就是 Promise.coroutine
不会给您任何错误的原因。对于生成器,您没有返回承诺。
initRouters()
returns 一台发电机。你不能 yield
到 Promise.coroutine
,这只允许你产生承诺(正如错误清楚地表明的那样)。
您要么需要将 initRouters
包装在 Promise.coroutine
中,要么使用
yield* initRouters();
以便产生来自生成器的所有承诺,而不是生成器本身。请注意,与 Bluebird 相比,co
库确实允许这种怪癖。