【问题标题】:Meteor helpers return nothing流星助手一无所获
【发布时间】:2016-11-20 11:53:16
【问题描述】:

我想为返回字符串数据创建助手:

  className() {

    let className;

    Meteor.call('getIp', (err, res) => {

      if (err) {
        console.log(err);
      } else {

        // User ip
        let ip = res.data.ip;
        let userLikers = this.likers;

        // Si l'utilisateur a déjà aimé le post
        if (userLikers.includes(ip)) {
          className = 'icon-favorite';
        } else {
          className = 'icon-favorite-border';
        }

        console.log(className);

        return className;

      }
    });

  }

我的console.log(className) 不错,不明白为什么我的return 是空的。

有人知道吗?

谢谢!

【问题讨论】:

    标签: meteor


    【解决方案1】:

    Meteor.call() 在客户端异步运行。与所有异步函数一样,它们使用回调函数。在您的情况下,这是代码的 (err, res) => { ... } 部分。

    这意味着return className;回调函数的返回值。但是,Meteor.call() 调用之前或之后的代码使用另一个范围。所以基本上classname() 函数不会返回任何东西,因为该函数没有返回语句。

    您可能想要的是将回调内部的数据分配给在回调调用之前声明的另一个变量。例如。像

    //Just for illustration.
    //Do NOT use it, as it will not work an will not do what you might think it does.
    className() {
    
        let value;
    
        Meteor.call('getIp', (err, res) => {
          //do other stuff like error handling
          // and getting the value here ...
    
          console.log(className);
          value = className;
        });
    
        return value;
    }
    

    但是,这仍然不能解释异步性。该函数很可能在回调触发之前返回。在这种情况下,您仍然会得到一个空的返回值。为避免这种情况,请尝试使用Meteor.wrapAsync()Meteor.call() 包裹在其中。这样就可以得到异步函数调用的返回值了。

    【讨论】:

    • 异步包装在客户端上不起作用(这是代码可能运行的地方)。我不知道在 Blaze 帮助程序中使用异步代码的任何优雅方式,除了具有反应性数据源。电话不是这些来源之一。
    • 是的,异步包装在客户端上不起作用。但是我如何检查我的数据?
    • 您解释了基本问题,这很好,但我认为发布无法可靠运行的代码不是一个好主意 - 因此它不是问题的解决方案。
    • 如果 Meteor.wrapAsync() 在客户端上不起作用,那么the official documentation 一定是误导,因为它说 wrapAsync() 可以在“任何地方”使用。
    • @Mikkel:是的,我知道上面的代码不会以可靠的方式工作(甚至根本不会,取决于执行速度)。这就是为什么我还写了不应该使用代码的原因。它仅用于说明目的。
    【解决方案2】:

    这里要记住的是服务器和客户端运行在不同的地方,一个在服务器上,一个在浏览器上。 Meteor 使这种差异变得不那么明显,并且可以在很大程度上无缝地传递数据。

    我使用的一种技术是让服务器方法将结果插入到 mongo 集合中。客户端上的助手会自动运行,客户端到了就可以显示。

    【讨论】:

      【解决方案3】:

      正如其他答案所指出的,在辅助函数(即渲染时)中使用 Meteor 方法(或其他异步代码)是行不通的。助手不能阻塞,所以不能等待服务器的结果。

      但是,看看您正在尝试做的事情,可能会有更好的解决方案。您的客户端代码正在向服务器询问它(客户端的)IP 地址是什么,以便您可以选择适当的 css 类。

      我建议您查看 Meteor 出色的 Accounts 软件包 - 它非常易于使用,并且会为您提供一种可靠的方式来识别用户。

      如果您想在不要求用户登录的情况下提供这种个性化,我建议您在客户端上存储一个永久 ID(即使用 random 模块生成、存储在 localStorage 中或通过 persistent-session)或类似的),或者只是在客户端上存储该用户喜欢的项目(帖子?)列表。

      这也避免了除非您的用户拥有静态 IP 地址,否则这些地址会经常更改。

      【讨论】:

        【解决方案4】:

        您可以尝试使用会话。加载模板时,调用您的方法并在回调中将返回值分配给会话。在助手中,您可以使用该会话返回有效数据,因为在开始时会话将是未定义的,但是当它在回调中设置时,助手将自动重新运行并且会话将返回有效值。希望这可以帮助您解决问题:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-07-16
          • 2015-04-15
          • 2015-09-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-20
          相关资源
          最近更新 更多