代码之家  ›  专栏  ›  技术社区  ›  Little Brain

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

  •  1
  • Little Brain  · 技术社区  · 7 年前

    我试图在异步函数中使用“await”,以避免回调。没有错误,但方法调用后的代码行会立即执行,并且不会提取方法的返回值。

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

    服务器:

    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
    

    没有错误,但显然不起作用;应该有两秒钟的延迟,应该是“得到结果奶酪”。

    我还尝试了以下服务器代码:

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

    这也行不通。

    感谢您的帮助。

    版本:

    METEOR@1.6.0.1

    babel运行时@^6.26.0

    react@16.2.0

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

    服务器:

    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 出现在控制台中。

    非常感谢。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Tolsee    7 年前

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

    在里面 async 功能,您可以 await 将暂停该功能,直到 Promise 已解决。所以 等候 不能与一起使用 Meteor.call ,它不会返回 许诺 .

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

    第一个客户端代码:

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

    我不知道你在第二个例子中想做什么。如果您认为,当您在方法中返回承诺时,客户将得到 许诺 ,这是错误的想法。承诺在服务器中得到解决,数据被传递回客户机,因此与客户机的角度没有任何区别。

    您要使用此库: 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)
          }
      });
    }