好吧,诺布在这里。还在学习。我不明白我如何让我的方法将我的Meteor.wrapAsync
函数的结果返回给客户端上的Meteor.call。我的方法中的console.log(companies);
生成一个函数,而不是结果。我在这里不理解什么?
路径:client.jsx
Meteor.call('getTop100ASX', (error, result) => {
console.log(result);
});
路径:method.js
Meteor.methods({
'getTop100ASX'() {
const aggregateFunc = db.collection('companiesASX').aggregate([{
$group: {
_id: {
location: "$google_maps.geometry_location"
},
companies: {
$addToSet: {
name: "$company_name"
}
}
}
}]).toArray((err, result) => {
return result;
});
const companies = Meteor.wrapAsync(aggregateFunc);
console.log(companies);
return companies;
},
});
答案 0 :(得分:2)
wrapAsync
包装一个通常需要回调的函数,并且可以使用fibers
以同步方式在服务器上调用该包装函数(即,接受函数+上下文并返回一个功能)。
它无法获取某些价值并从中神奇地提取预期结果(例如,在您的示例中,result
回调中的toArray
。
你给它的不是一个函数,而是一个Promise
对象(从调用toArray
返回的)。
由于它已经返回一个承诺,你有几个选择:
更简单的是返回该promise(并且不需要toArray()
中的回调),因为如果Meteor方法返回一个promise,服务器将等待promise解析然后返回结果给客户。
Meteor.methods({
'getTop100ASX'() {
return db.collection('companiesASX').aggregate([...]).toArray();
},
});
如果您需要在方法中进一步处理companies
,可以使用async / await,例如:
Meteor.methods({
async 'getTop100ASX'() {
const companies = await db.collection('companiesASX').aggregate([{
$group: {
_id: {
location: "$google_maps.geometry_location"
},
companies: {
$addToSet: {
name: "$company_name"
}
}
}
}]).toArray();
let someResult = sumeFunc(companies);
return someResult;
},
});
为了完整性,为了使用wrapAsync
,您应该提供toArray
方法和上下文,如下所示:
Meteor.methods({
'getTop100ASX'() {
const cursor = db.collection('companiesASX').aggregate([{
$group: {
_id: {
location: "$google_maps.geometry_location"
},
companies: {
$addToSet: {
name: "$company_name"
}
}
}
}]);
// wrap the cursor's `toArray` method and preservs the context
const syncToArray = Meteor.wrapAsync(cursor.toArray, cursor);
// and call the wrapped function in a sync manner
const companies = syncToArray();
return companies;
},
});