结果未定义的流星方法回调

Meteor Method callback getting undefined for result

我有一段时间没有用 Meteor 编写代码了,但是我有这个 Meteor 方法可以创建一个任务和 returns 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 也更改为 link,但我想尝试弄清楚为什么它没有将 Meteor 方法的结果获取到客户端的回调中-side.

您需要 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

关于 collection methods 的 Meteor API 文档像 insert 说了以下内容:

On the server, if you don’t provide a callback, then insert blocks until the database acknowledges the write, or throws an exception if something went wrong. If you do provide a callback, insert still returns the ID immediately. Once the insert completes (or fails), the callback is called with error and result arguments. In an error case, result is undefined. If the insert is successful, error is undefined and result is the new document 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);
      }
    });
  }
});

这会 return 立即生成新的 ID,但缺点是之后会抛出错误。因此你最好直接执行 "sync-like":

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

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

如果您关心代码的同步性质,请阅读this part of the guide关于方法的内容。

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

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

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