在 Meteor / React 项目中等待不起作用

await in Meteor / React project doesn't work

我正在尝试在异步函数中使用 'await' 以避免回调。没有错误,但是方法调用后的代码行会立即执行,并且不会从方法中获取 return 值。

我正在使用 React,但我认为这不会影响这段代码。我假设 async 和 await 命令是由 babel-运行time 提供的,所以我不需要手动包含任何其他内容?我已经阅读了许多示例和教程,并尝试了很多变体,但都没有成功。我一定是遗漏了一些非常基本的东西,但我想不通。

服务器:

Meteor.methods({
    'asyncTest': function() {
        setTimeout(() => {return 'cheese';}, 2000);
    }
});

客户:

Meteor.myFunctions = {
    'test': async function Test() {
        let result1 = await (Meteor.call('asyncTest'));
        console.log(`got result ${result1}`);
    },
};

当我在浏览器控制台中 运行 Meteor.myFunctions.test() 时,我立即看到以下输出:

Promise { "pending" }
<state>: "pending"
__proto__: PromiseProto { done: common.js/exports.Promise.prototype.done(), … }
got result undefined

没有报错,但是明显不行;应该有两秒的延迟,它应该说 "got result cheese".

我也试过这个服务器代码:

import { Promise } from 'meteor/promise';

Meteor.methods({
'asyncTest': function() {
    return new Promise(resolve => {
            setTimeout(() => {console.log('cheese'); resolve('cheese');}, 2000);
        });
    },
});

这也不行。

感谢收到的任何帮助。

版本:

流星@1.6.0.1

babel-运行time@^6.26.0

react@16.2.0

编辑 2:我得到了@Tolsee 的建议 :) 除其他事项外,我在我的测试方法中犯了一个愚蠢的错误,使用 setTimeout 来延迟 return。当然这不起作用,因为在超时结束时调用的函数不是方法。此代码对我有用:

服务器:

Meteor.methods({
'asyncTest': function() {
        var timeNow = new Date();
        while (new Date().getSeconds() < timeNow.getSeconds() + 3) {
        }
        return 'cheese';
    },
});

客户:

success = function(res) {
    console.log('result ' + res);
}

failure = function(err) {
    console.log('failure ' + err);
}

promisedCall = function(method) {
    return new Promise((resolve, reject) => {
        Meteor.call(method, (err, res) => {
            if (err) {
                reject(err);
            } else {
                resolve(res);
            }
        });
    });
};

运行 控制台中的代码:promisedCall('asyncTest').then(success, failure);

正如预期的那样,有 3 秒的延迟,然后 result cheese 出现在控制台中。

谢谢!

首先,async-await是由javascript提供的,不是babel。

async 函数中,您可以使用 await 暂停函数,直到 Promise 得到解决。因此,await 不能与 Meteor.call 一起使用,后者不 return Promise

现在,让我们看看您的代码:

第一个客户端代码:

Meteor.myFunctions = {
    'test': async function Test() {
        let result1 = await (Meteor.call('asyncTest')); // Bucause Meteor.call does not return promise.
        console.log(`got result ${result1}`);
     },
};

我不知道你在第二个例子中试图做什么。如果您认为当您在方法中 return 承诺时,客户端将获得 Promise,这是错误的想法。承诺在服务器中解析,数据传回客户端,因此从客户端的角度来看没有任何区别。

你想使用这个库:https://github.com/deanius/meteor-promise

编辑: 您可以自己创建一个简单的承诺方法调用函数。

function promisedCall(method) {
  return new Promise((resolve, reject) => {
    Meteor.call(method, (err, res) => {
      if (err) {
        reject(err)
      } else {
        resolve(res)
      }
  });
}