【问题标题】:Wait for node.js callback to be completed before ending AJAX request在结束 AJAX 请求之前等待 node.js 回调完成
【发布时间】:2013-09-26 08:00:33
【问题描述】:

我在前面使用 jQuery 来使用 $.post() 发出 AJAX 发布请求。我还传递了一个成功函数,它将对返回的数据做一些事情。在我的 node.js 服务器上,我使用 express 来处理请求,发布请求调用另一个传递回调的函数,该回调在回调中执行 res.send()。如何让请求在回调完成之前不完成?

我的客户端代码是:

$.post("/newgroup/", {name: newgroupname}, function(data) {
    console.log(data); // Returns undefined because requests ends before res.send
});

我的服务器端代码是:

app.post('/newgroup/', function(req, res){
    insertDocument({name:req.body.name, photos:[]}, db.groups, function(doc){
        res.send(doc); 
    });
});

insertDocument函数是:

function insertDocument(doc, targetCollection, callback) {
    var cursor = targetCollection.find( {}, {_id: 1}).sort({_id: -1}).limit(1);
    cursor.toArray(function(err, docs){
        if (docs == false){
            var seq = 1;
        }
        else {
            var seq = docs[0]._id + 1;
        }
        doc._id = seq;

        targetCollection.insert(doc);
        callback(doc);
    });
}

【问题讨论】:

  • 我觉得还有别的。在调用 res.send() 之前,该响应应该发送任何内容。 $.post() 应该等待 res.send()。确保你没有在其他地方调用它。
  • 您是否验证了新闻组帖子处理程序实际上正在被调用?
  • 您是否查看过 chrome 开发人员工具或 firebug 中的网络流量以查看实际发送的 XHR 以及它发回给您的响应?看看实际响应是什么样的,并将其与您在console.log(data) 语句中看到的结果进行比较会很有趣。

标签: ajax node.js jquery express


【解决方案1】:

可能是 同步/异步 问题吗?我不知道您使用什么库进行保存,但调用是否应该更像这样?

targetCollection.insert(doc, function(err, saveddoc) {
    if (err) console.log(err);
    callback(saveddoc);
});

【讨论】:

  • 这也是异端邪说。首先:if/else 创建作用域(只有函数可以)。代码很好。其次:对象是通过引用传递的。将变量传递给将修改它的函数是不可能的(它可能会修改底层对象,但不会修改变量)。
  • @freakish 那么,我想我们每天都在学习。那个怎么样。了解取消引用问题,深夜监督......我将为社区编辑虚假内容。
【解决方案2】:

好的,我找到了答案,我不确定为什么会这样,我只需要更改我发送给回调的变量的名称,我认为这是因为它与参数具有相同的名称,所以我将我的 insertDocument 函数更改为如下所示

function insertDocument(doc, targetCollection, callback) {
    var cursor = targetCollection.find( {}, {_id: 1}).sort({_id: -1}).limit(1);
    cursor.toArray(function(err, docs){
        if (docs == false){
            var seq = 1;
        }
        else {
            var seq = docs[0]._id + 1;
        }
        doc._id = seq;

        targetCollection.insert(doc);
        var new_document = doc;
        callback(new_document);
     });
}

【讨论】:

  • 那是异端邪说。 :D 我绝对不相信这是解决方案。
  • @freakish 这正是我的想法,但不知何故改变了它导致它工作!
  • 我认为这并不能解决您的想法。请参阅我上面的帖子。
【解决方案3】:

如果您向我们展示的代码是真实代码,那么唯一的可能性是您返回的 doc 实际上是 undefined。在触发res.send() 之前,客户端上的回调不会触发。

您确定insertDocument 中的回调与您想的完全一样吗?回调通常采用function(err,doc) 的形式,即试试这个:

app.post('/newgroup/', function(req, res){
    insertDocument({name:req.body.name, photos:[]}, db.groups, function(err, doc){
        res.send(doc); 
    });
});

【讨论】:

  • 我试过了,但由于某种原因它不起作用。我在原始问题中添加了 insertDocument 函数。我在回调中控制日志文档,它始终未定义。
  • 我还在回调(doc)之前放置了一个console.log;并且它正确显示了文档,但是由于某种原因,当回调将文档发回时,它变得未定义。这与范围有关吗?
  • @Jupiter 确实很奇怪。如果这是整个代码,那么就没有任何东西可以修改 doc 变量(我不是在谈论底层对象),即范围在这里不是问题。老实说,我不确定您向我们展示的代码如何导致这样的结果。也许还有更多事情你没有与我们分享?
  • 我似乎找到了一些可行的方法。请参阅下面的答案,我认为这与变量名与初始参数相同有关,但我不明白为什么这会起到很大作用。无论如何,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-12
  • 2016-02-17
  • 2016-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多