我正在使用带有node.js的rethinkDB。以下请求可以正常工作:
function myFn () {
return co(function *() {
let query;
query = yield r.db("my-db")
.table("app")
.filter(r.row("id").eq(id))
.run(conn);
return query.toArray();
});
}
我想异步返回多个yield
的结果,但是以下失败:
function myFn () {
return co(function *() {
let query, query2;
query = r.db("my-db")
.table("app")
.filter(r.row("id").eq(id))
.run(conn);
query2 = r.db("my-db")
.table("app")
.filter(...)
.run(conn);
return yield {q1 : query, q2 : query2};
});
}
然后我必须在每个元素上调用toArray()
,所以我在调用函数上执行:
// using ramda.js
var res = R.map((el) => {
return el.toArray();
}, yield myFn);
但是我得到了:
{
"q1": {
"isFulfilled": false,
"isRejected": false
},
"q2": {
"isFulfilled": false,
"isRejected": false
}
}
奇怪的是:
// this works perfectly
return q.toArray();
// this returns the following :
return {q: q.toArray()};
"q": {
"isFulfilled": true,
"isRejected": false,
"fulfillmentValue": [ ... ]
}
我怀疑我遗漏了yield
的工作方式,所以如何才能返回多个yield
结果的实现结果?
答案 0 :(得分:1)
yield
不能处理包含promises的对象 - 它只适用于promises本身。而不是return yield {q1: query, q2: query2};
你必须做
return {q1: yield query, q2: yield query2};
然而,这有点问题,因为在query2
完成之前不会抛出query
中的错误。因此,如果您不是just want to sequentially execute them,则必须使用Promise.all
来等待承诺的集合"并行":
var [q1, q2] = yield Promise.all([query, query2]);
return {q1, q2};
(根据您正在使用的promise lib,可能还有一个辅助函数将对象视为集合,而不仅仅是数组)
答案 1 :(得分:1)
所以我在reThinkDB google groups
上问了同样的问题:
引用Ryan Paul的话:
你原来的尝试实际上非常接近,只有两次 你需要添加的东西:
- 您需要单独提出查询
- 如果您不想获取游标,则需要在查询中转换为数组
这是一个关于协程和产量的工作示例:
function myFn() { return co(function*() { var conn = yield r.connect(); var query1 = yield r.db("test").table("fellowship") .filter({species: "hobbit"}) .coerceTo("array").run(conn); var query2 = yield r.db("test").table("fellowship") .filter({species: "human"}) .coerceTo("array").run(conn); conn.close(); return {q1: query1, q2: query2}; }); }
没有协同程序和产量,这也很简单 只要你使用像蓝鸟这样的诺言库。这就是我要做的 它:
function myFn1() { return r.connect().then(conn => { return bluebird.all([ r.db("test").table("fellowship") .filter({species: "hobbit"}) .coerceTo("array").run(conn), r.db("test").table("fellowship") .filter({species: "human"}) .coerceTo("array").run(conn) ]).then(items => ({q1: items[0], q2: items[1]})); }); }