2013-09-20 3 views
1

Я использую jQuery на передней панели, чтобы сделать запрос на отправку AJAX, используя $ .post(). Я также передаю функцию успеха, которая будет делать что-то с возвращенными данными. На моем сервере node.js я использую выражение для обработки запросов, post request вызывает другую функцию, передающую обратный вызов, который в обратном вызове выполняет res.send(). Как я могу заставить запрос не закончаться, пока не будет выполнен обратный вызов?Дождитесь завершения обратного вызова node.js перед завершением запроса AJAX

Мой стороне клиента код:

$.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); 
    }); 
} 
+2

Я думаю, что есть что-то еще. Этот ответ должен отправлять что-либо до вызова res.send(). $ .post() должен ждать res.send(). Убедитесь, что вы не звоните в другое место. –

+0

Вы подтвердили, что обработчик почтовой группы фактически вызывается? – pdoherty926

+0

Вы просматривали сетевой трафик в хром-инструментах разработчика или firebug, чтобы увидеть, как отправляется фактический XHR, и ответ, который он отправляет вам? было бы интересно посмотреть, как выглядит фактический ответ, и сравнить это с результатом, который вы видите в инструкции 'console.log (data)'. – guydog28

ответ

1

Если код, который вы показал нам реальный код, тогда единственная возможность заключается в том, что вещь, которую вы возвращаете 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); 
    }); 
}); 
+0

Я пробовал это, и он почему-то не работал. Я добавил функцию insertDocument в исходный вопрос. Я завершаю log doc в обратном вызове, и он всегда не определен. – Jupiter

+0

Также я помещаю console.log перед обратным вызовом (doc); и он правильно отображает документ, но по какой-то причине, когда обратный вызов отправляет документ обратно, он становится неопределенным. Будет ли это связано с областью? – Jupiter

+0

@ Юпитер Очень странно. Если это весь код, то нет ничего, что изменяет переменную doc (я не говорю о базовом объекте), то есть область охвата здесь не проблема. Я не уверен, как код, который вы нам показали, может привести к тому, что такой результат будет честным. Возможно, есть что-то еще, что вы не делитесь с нами? – freakish

0

Хорошо, я нашел ответ, я не знаю, почему это работает, я просто должен был изменить имя переменной я отправлял на обратный вызов, Я предполагаю, что это потому, что он имел такое же имя в качестве параметра, поэтому я изменил свою функцию 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); 
    }); 
} 
+0

Это ересь. : D Я абсолютно не считаю, что это решение. – freakish

+0

@freakish Это именно то, о чем я думал, но как-то изменилось, что заставило его работать! – Jupiter

+0

Я не думаю, что это решает то, что вы думаете. См. Мой пост выше. – guydog28

0

Может быть синхронной/асинхронной вопрос? Я не знаю, какую библиотеку вы используете для ваших сейвов, но разве дело в том, что вызов должен быть чем-то более подобным?

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

Это тоже ересь. Прежде всего: 'if/else' block ** не создает ** область (только функции выполняют). Код в порядке. Во-вторых: объекты передаются по ссылке. Невозможно передать переменную функции, которая будет ее изменять (она может изменить базовый объект, но не переменную). – freakish

+0

@ freakish Ну, тогда, я думаю, мы учимся каждый день. Как насчет этого. Поймите проблему разыгрывания, ночной надзор там ... Я отредактирую ложности для сообщества. – guydog28

Смежные вопросы