Meteor:如何使用2个参数调用函数并等待结果

时间:2017-08-03 19:50:34

标签: javascript asynchronous meteor async-await

过去几天我一直在阅读有关promiseswait/asyncfibers的内容,但我还是无法解决这个问题。我很难找到一个简单的例子,展示我如何能做出这样的事情:

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让它等待?

2 个答案:

答案 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很简单,但我建议坚持Promiseasync / 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块来捕获任何错误。