如何在客户端nodejs处理异步请求?

时间:2016-03-10 13:30:43

标签: javascript node.js mongodb asynchronous

我是NodeJS的新手。我在服务器端使用NodeJS。我正在尝试创建一个简单的基于REST的GET请求,该请求从用户获取搜索参数searchvar并返回在JSON数组中找到的匹配记录。我的服务器代码如下:

var express = require('express');
var app = express();
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var ObjectId = require('mongodb').ObjectID;
var url = 'mongodb://localhost:27017/mydb';

app.get('/search', function(req, res) {
  res.set({ 'content-type': 'application/json; charset=utf-8' });
  res.header("Content-Type", "application/json; charset=utf-8");
  res.charset = 'utf-8';

  var searchvar = req.query.searchvar;

  if(searchvar != null) {
    var recordsArray = new Array();
    console.log("searchvar :: " + searchvar );

    MongoClient.connect(url, function(err, db) {
      var cursor = db.collection('myCollections').find({"name": new RegExp(searchvar)});
      cursor.each(function(err, doc) {
        //assert.equal(err, null);
        if (doc != null) {
          var tempObject = {"name": doc.name, "cat": doc.cat};
          recordsArray.push(tempObject);
          console.dir(doc);
        } else {
          db.close();
        }
      });

      if(recordsArray.length > 0) {
        console.log("if........");
        res.json({"status": "SUCCESS", "message": "The request processed successfully.", "records":recordsArray});
      } else {
        console.log("else........");
        res.json({"status": "FAILURE", "message": "No records found corresponding to given search query."});
      }
    });
  } else {
    res.json({"status": "FAILURE", "message": "The searchvar is missing."});
  }

  //res.send('id: ' + req.query.id);
});

app.listen(3000);

当我在具有以下URL的浏览器中使用RESTClient调用它时:

http://localhost:3000/search?searchvar=aa

我得到以下回复:

  

{“status”:“FAILURE”,“message”:“找不到与给定搜索查询相对应的记录。”}

这是一个异步调用。我想知道服务器中使用的进程,我可以在处理完成后返回响应并在客户端处理此异步响应。 提前谢谢。

3 个答案:

答案 0 :(得分:3)

响应的发生是因为if检查:

if(recordsArray.length > 0) {
    console.log("if........");

在传递给cursor.each方法的回调完成其处理之前执行。结果,数组为空。

提议的解决方案
cursor.forEach方法采用异步执行的回调函数。这意味着您只能在回调本身内访问回调执行的结果(除了返回Promise对象)。修复将是:

cursor.forEach(function(doc) {
  if (doc != null) {
    var tempObject = {"name": doc.name, "cat": doc.cat};
    recordsArray.push(tempObject);
    console.dir(doc);
  }
}, function(err) {
  if(recordsArray.length > 0) {
    console.log("if........");
    res.json({"status": "SUCCESS", "message": "The request processed successfully.", "records":recordsArray});
  } else {
    console.log("else........");
    res.json({"status": "FAILURE", "message": "No records found corresponding to given search query."});
  }
  db.close();
});

答案 1 :(得分:1)

我认为你错过了MongoClient Collection find()方法的回调参数。您应该将处理逻辑移到回调中。

请参阅MongoDB文档中的这些examples

您的代码看起来像这样:

db.collection('myCollections').find({"name": new RegExp(searchvar)}).toArray(function(err, docs) {
    // iterate through docs; perform your logic
    db.close();
    res.json({...});
});

答案 2 :(得分:0)

我认为最好的办法是通过Nodejs / MongoDB tutorial来了解一切是如何运作的。通过快速查看代码,您的响应不是异步的。任何时候服务器立即响应它都不是异步。当您实现诸如Websockets或HTTP Callbacks之类的东西时,在服务器端实现异步。

我同意Jim的意见,问题可能出在您的客户身上(如果您仍有疑问,请发布代码)。通常,JS客户端通过使用回调或承诺实现异步,但异步客户端不需要异步服务器。进行异步客户端调用的常见原因是您在等待服务器响应时不会锁定GUI。