过去几天我一直在阅读有关promises,wait/async和fibers的内容,但我还是无法解决这个问题。我很难找到一个简单的例子,展示我如何能做出这样的事情:
Meteor.methods({
theMethod: function(){
var numberOne = 4;
var numberTwo = 5;
var result = calculateNumber(numberOne, numberTwo);
console.log('This is the result: ', result);
}
});
calculateNumber = function(numberOne, numberTwo){
var result = numberOne + number Two
//but lets assume an ultra complex calculation that takes a while
return result;
}
如何使console.log等待结果返回时没有回调但是await / wrapAsync语法?
提前致谢! :)
编辑:
以下是我尝试过的代码:
Meteor.methods({
theMethod: async function(){
const no1 = 4, no2 = 5;
//calculateNumber should return a promise, if it doesnt, Promise.resolve makes the returned value a promise
const calculateNumberPromise = Promise.resolve(calculateNumber(no1, no2));
const res = await calculateNumberPromise;
console.log('Number calculated', res);
//the number can be returned directly to the client:
return res
}
});
calculateNumber = function(no1, no2){
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
sleep(5000).then(() => {
return no1 + no2;
});
}
有没有办法在calculateNumber之后让所有东西等待?如果那是不可能的,我在哪里/如何嵌套console.log让它等待?
答案 0 :(得分:3)
仅使用Promise
(即没有async
/ await
),您可以执行以下操作:
Meteor.methods({
theMethod: () => {
const no1 = 4, no2 = 5;
//calculateNumber should return a promise, if it doesnt, Promise.resolve makes the returned value a promise (unless calculateNumber is a sync function ie takes a callback)
const calculateNumberPromise = Promise.resolve(calculateNumber(no1, no2));
//If you want to log the output regardless:
calculateNumberPromise
.then(res => console.log('Number calculated', res))
.catch(err => console.log('Error calcualting number', err))
//The promise is resolved before the data is sent over the wire.
return calculateNumberPromise;
}
});
在客户端上,可以调用此方法并使用promise。理想情况下,您现在应该使用validated methods。结合经过验证的方法,您可以使用callPromise mixin。示例链接。可以在流星指南中找到更多validated method examples。
将以前的代码段调整为使用async
很简单:
Meteor.methods({
theMethod: async function() {
const no1 = 4, no2 = 5;
//calculateNumber should return a promise, if it doesnt, Promise.resolve makes the returned value a promise
const calculateNumberPromise = Promise.resolve(calculateNumber(no1, no2));
const res = await calculateNumberPromise;
console.log('Number calculated', res);
//the number can be returned directly to the client:
return res;
}
});
注意在函数定义中添加了async
。还可以找到优秀的写作here - 请查看Rob Fallows的其他文章。
wrapAsync
很简单,但我建议坚持Promise
和async
/ await
。如果您真的想要使用它,可以在Meteor chef's site找到一些旧的(但很好的)示例。
如果其中任何一项不清楚,请要求澄清。
答案 1 :(得分:1)
在Meteor中使异步函数同步的最简单方法是用Meteor.wrapAsync
包装它对于你的例子:
Meteor.methods({
theMethod() {
const numberOne = 4;
const numberTwo = 5;
const result = Meteor.wrapAsync(asyncFun(numberOne, numberTwo));
console.log('This is the result: ', result);
}
});
您的calculateNumber
功能与您在问题中列出的方式同步,wrapAsync
旨在包装真正的异步功能。请注意长时间运行!==异步。另请注意,您要包装的异步函数必须返回错误和结果,而不仅仅是结果。当然,当您使用wrapAsync
时,结果将返回到调用代码,因此您需要使用try/catch
块来捕获任何错误。