【问题标题】:How to handle async request at client nodejs?如何在客户端 nodejs 处理异步请求?
【发布时间】:2016-06-25 09:11:52
【问题描述】:

我是 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": "没有找到与给定搜索查询对应的记录。"}

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

【问题讨论】:

  • 对您视为异步进程的服务器的任何调用都将在客户端严格处理。在客户端,您正在向服务器发起 AJAX 调用,然后服务器将控制权交还给调用它的脚本,并返回一个包含 AJAX 请求状态的对象。创建 AJAX 请求的代码负责定期检查 AJAX 对象是否已收到响应,然后必须对其进行操作。幸运的是,有许多抽象通过承诺和/或回调的形式使这更容易。这适用于浏览器或节点客户端。

标签: javascript node.js mongodb asynchronous


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    我认为您缺少 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({...});
    });
    

    【讨论】:

      【解决方案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();
      });
      

      【讨论】:

      • cursor.each 方法已被弃用,也没有按照您的要求进行。正确的方法是cursor.forEach,它具有“两者”一个迭代器和一个回调来指示迭代何时实际完成。 OP 的列表和您的代码实际上都在迭代器“内部”工作。在您的情况下,在每次迭代时都试图发送响应“和”挂断数据库连接。这将严重失败。
      • 非常感谢您指出这一点。我已经解决了。
      猜你喜欢
      • 2018-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 2018-05-21
      相关资源
      最近更新 更多