【问题标题】:Meteor Method callback getting undefined for resultMeteor 方法回调的结果未定义
【发布时间】:2018-01-10 12:49:28
【问题描述】:

我已经有一段时间没有在 Meteor 中编码了,但是我有这个 Meteor 方法,它创建一个任务并返回 ID 和另一个将该任务附加到项目的方法:

Meteor.methods({
  createTask(task) {
    // TODO Add a check here to validate
    Tasks.insert(task, (err, id) => {
      if (err) {
        throw new Meteor.Error(err);
      }
      id = {id: id};
      console.log('Returning id: ', id);
      return id;
    });
  }
});

Meteor.methods({
  appendTaskToProject(projectId, taskId) {
    // TODO Add check here to validate
    const project = Projects.findOne({_id: projectId});
    if (project) {
      if (!project.tasks) {
        project.tasks = [];
      }
      project.tasks.push(taskId);
      Projects.update({_id: projectId}, project, (err, id) => {
        if (err) {
          throw new Meteor.Error(err);
        }
      });
    } else {
      throw new Error("Could not find project");
    }
  }
});

我正在尝试像这样在客户端上调用它:

Meteor.call('createTask', task, (err, taskId) => {
  console.log('err: ', err);
  console.log('taskId: ', taskId);
  if (err) {
    this.setState({ error: err.message});
  } else {
    Meteor.call('appendTaskToProject', projectId, taskId, (err, result) => {
      if (err) {
        this.setState({ error: err.message});
      } else {
        this.setState({ newTaskDialogOpen: false })
      }
    });
  }
});

我遇到的问题是taskId 没有在回调中设置。从方法端我看到服务器中的日志消息如下:

I20180110-07:30:46.211(-5)? Returning id:  { id: 'a3nS9GcRhuhhLiseb' }

在客户端:

Returning id:  {id: "a3nS9GcRhuhhLiseb"}id:
Tasks.jsx:43 err:  undefined
Tasks.jsx:44 taskId:  undefined

所以我知道它正在返回一些东西,但回调只是没有得到它。我知道我可能应该将 createTask 更改为只接受任务和 projectId 来链接它,但我想尝试弄清楚为什么它没有将 Meteor 方法的结果输入到客户端的回调中。

【问题讨论】:

  • 您是否尝试过使用非回调样式(const result = MyCollection.insert(...);)?

标签: javascript meteor meteor-methods


【解决方案1】:

collection methods 上的 Meteor API 文档(如 insert)说明如下:

在服务器上,如果您不提供回调,则插入块 直到数据库确认写入,或者抛出异常,如果 出问题了。如果您确实提供了回调,请插入 立即返回 ID。一旦插入完成(或失败), 使用错误和结果参数调用回调。在错误情况下, 结果未定义。如果插入成功,则错误未定义 结果是新的文档 ID。

将此信息应用于您的代码将创建以下内容:

Meteor.methods({
  createTask(task) {
    // TODO Add a check here to validate
    return Tasks.insert(task, (err, id) => {
      if (err) {
        throw new Meteor.Error(err);
      }
    });
  }
});

这会立即返回新生成的 ID,但缺点是之后会抛出错误。因此,您最好采用直接方式并执行“类似同步”:

Meteor.methods({
  createTask(task) {
    // TODO Add a check here to validate
    return Tasks.insert(task);
  }
});

meteor 方法自动包装代码,以便在正返回时,您的客户端将收到 null 错误值和 _id 值作为结果。如果插入过程中发生错误,该方法会自动在客户端回调中将错误作为错误返回,reuslt 将为空。

如果您关心代码的同步特性,请阅读this part of the guide about methods。

同样适用于您的更新方法:

Meteor.methods({
  appendTaskToProject(projectId, taskId) {
    // TODO Add check here to validate
    return Projects.update({_id: projectId}, {$push: {tasks: taskId});
  }
});

请注意,我将此方法总结为更面向 mongo 的方法。

【讨论】:

  • 谢谢。我想我在阅读文档网站时错过了那部分。
【解决方案2】:

您需要在插入回调之外return id。

Meteor.methods({
  createTask(task) {
    // TODO Add a check here to validate
    var returnID;
    Tasks.insert(task, (err, id) => {
      if (err) {
        throw new Meteor.Error(err);
      }
      id = {id: id};
      returnID = id;
      console.log('Returning id: ', id);
      // return id; --not here
    });
   return returnID; //return it here.
  }
});

可能的解释可以在here找到。

【讨论】:

  • 这不起作用,因为该方法在调用回调之前返回。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-18
  • 1970-01-01
  • 2013-04-24
  • 2011-03-01
相关资源
最近更新 更多