Javascript似乎没有正确返回Parse对象

时间:2015-03-17 21:20:14

标签: javascript parse-platform

我有一个名为makeNewNode()的函数,该函数应该使用Parse GeoPoint对象并返回一个名为node的(自定义)Parse对象,该对象包含一个GeoPoint对象,其中包含键" location"和一个指向另一个自定义Parse对象的指针,键是"停止。"这个功能应该做的主要是" snap"如果节点在其GeoPoint的SNAP_RADIUS内有一个节点。如果没有,返回一个带有null" stop"的全新节点。指针和"位置"参数geoPoint

我对此代码有几个问题。

首先,似乎总是无法返回任何东西。 Parse查询总是返回成功,这很好。但是,它只会在“快照”时返回可用的内容。"否则它只返回一个未定义的results变量。

第二个(也就是主要的)是无论是否捕捉,该函数都不会返回任何远程类似于我期望的节点对象。这使我相信通过广泛使用console.log节点永远不会被查询的成功函数中的操作更改或影响。

第三个与更广泛意义上的前一个相关。每次我试图从Javascript中的函数返回一个对象时,它都没有按照我预期的方式行事。每当我尝试从查询的成功函数中更改变量时,实际上没有任何变化。我对这个更深入的Javascript有点新意,因为我之前的经历更加轻松。

这是一个麻烦的代码。

function makeNewNode(geoPoint) {
  var node = {};
  var Node = Parse.Object.extend("Nodes");
  var query = new Parse.Query(Node);
  query.withinMiles("location",geoPoint,SNAP_RADIUS);
  query.first({
    success: function(results) {
      console.log(results);
      console.log(results + "");
      if (results == undefined) {
        node = new Node();
        node.set("location",geoPoint);
        node.set("stop",null);
        node.save();
        console.log(node.id);
      } else {
        node = results;
      }
    },
    error: function(error) {
      console.log("Failed to create a node. Error: " + error.message + ".");
    }
  });
  return node;
}

这就是我所说的。

var geoPoint = new Parse.GeoPoint(location.lat(),location.lng());
var newnode = makeNewNode(geoPoint);

非常感谢有关我的代码或三个问题之一的任何想法或建议。

2 个答案:

答案 0 :(得分:2)

更简洁的方法是使用promises,这样就可以在没有额外回调参数的情况下处理新创建的对象的保存,并且不会创建更深入和更深的成功函数嵌套。此外,调用者可能希望将节点作为一组更大的异步步骤的一部分。

承诺版本如下:

// return a promise that, when fulfilled, creates a new node with
// at the geoPoint, or, if a node exists within SNAP_RADIUS, returns that node
function makeNewNode(geoPoint) {
    var Node = Parse.Object.extend("Nodes");
    var query = new Parse.Query(Node);
    query.withinMiles("location",geoPoint,SNAP_RADIUS);
    return query.first().then(function(node) {
        if (!node) {
            node = new Node();
            node.set("location", geoPoint);
            node.set("stop", null);
        }
        return (node.isNew())? node.save() : Parse.Promise.as(node);
    });
}

调用者现在可以将其与其他承诺链接起来。

编辑 - 以下是您如何称呼它。让我们说我们在另一个异步调用中得到geoPoint,然后......

var geoPoint = new Parse.GeoPoint(location.lat(),location.lng());
makeNewNode(geoPoint).then(function(newNode) {
    console.log("new node id is " + newNode.id);
}, function(error) {
    console.log("error " + error.message);
});

所有回报是什么?承诺是结果的占位符。返回它给调用者和对象提供了一个完成函数(使用then()方法)。完成回调也可以返回一个promise(这是内部返回),这样它们就可以被任意链接。 then()的第二个参数是一个可选的回调来处理失败。

答案 1 :(得分:1)

我不知道你是否知道异步问题,但它们可能是问题所在。

function makeNewNode(geoPoint) {
  var Node = Parse.Object.extend("Nodes");
  var node = new Node();
  var query = new Parse.Query(Node);
  query.withinMiles("location",geoPoint,SNAP_RADIUS);
  query.first({
    success: function(results) {
      console.log(results);
      console.log(results + "");
      if (results == undefined) {
        node.set("location",geoPoint);
        node.set("stop",null);
        node.save(function() {
          console.log(node.id);
        });
      } else {
        node.set("location", results.get("location"));
        node.set("stop", results.get("stop"));
      }
    },
    error: function(error) {
      console.log("Failed to create a node. Error: " + error.message + ".");
    }
  });
  return node;
}

query.first()是一个异步函数。当您的函数返回时,异步函数可能没有调用您的回调。在这种情况下,返回值将是您在开头定义的对象{}

稍后当您将新值(new Node()等)分配给node时,返回的值仍然是上一个对象,而不是分配给node的新对象。< / p>

简单的解决方法是使用预先指定的对象进行返回,并在以后更新其内容,就像我上面的示例一样。

但是,对于异步代码段,这绝不是一个好的解决方案。您应该使用回调或承诺来返回新的Node

使用回调就像:

function makeNewNode(geoPoint, callback) {
  var Node = Parse.Object.extend("Nodes");
  var node;
  var query = new Parse.Query(Node);
  query.withinMiles("location",geoPoint,SNAP_RADIUS);
  query.first({
    success: function(results) {
      console.log(results);
      console.log(results + "");
      if (results == undefined) {
        node.set("location", geoPoint);
        node.set("stop", null);
        node.save(function() {
          console.log(node.id);
          callback(null, node);
        });
      } else {
        callback(null, results);
      }
    },
    error: function(error) {
      console.log("Failed to create a node. Error: " + error.message + ".");
      callback(error);
    }
  });
}

你可以像以下一样使用它:

makeNewNode(geoPoint, function(err, newNode) {
  // use your new Node here.
})