찾다

 >  Q&A  >  본문

express - node.js中操作mongodb, 如何解决异步的问题?

我在使用node.js + express + mongodb做一个英语课堂测试系统, 其中有一个学生管理界面. 新增一个学生, 有以下字段: name(名称), age(年龄), grade(年级)等, 于是我封装了一个判断函数, 用于判断前端所传递的数据是否有误:

  // 检查所传入的数据是否有效
  function check_info(_id, name, age, grade) {
    if ("" == name) {
      return {status: false, msg: '名称不可为空'};
    }
    age = parseInt(age);
    grade = parseInt(grade);
    if (isNaN(age)) {
      return {status: false, msg: '年龄必须为整数'};
    }
    if (isNaN(grade)) {
      return {status: false, msg: '年级必须为整数'};
    }
    console.log("1");
    if (_id) {
      collection.find({_id: _id, name: name}).count(function (err, count) {
        if (1 != count) {
          return {status: false, msg: '编辑情况下, 名称不可更改!'};
        }
      });
    } else {
      console.log("2");
      collection.find({name: name}).count(function (err, count) {
        console.log("3");
        if (0 != count) {
          return {status: false, msg: '新增情况下, 数据库中已经存在此名称!'};
        }
      });
    }
    console.log("4");
    return {status: true, msg: '正确'};
  }

在这里, 很明显, 由于find数据库时候, 采用的是异步操作, 导致永远返回{status: true, msg: '正确'};

问题:

  1. 在实际项目中, 是如何解决这种情况的? 我查了数据库, 貌似还没有同步的解决方案出现?

  2. 我没有使用mongoose, 使用的是mongodb的本身api:

var express = require('express');
var router = express.Router();
var init = function (callback) {
var MongoClient = require('mongodb').MongoClient;
  var url = 'mongodb://localhost:27017/test_system';
  MongoClient.connect(url, function (err, db) {
    var collection = db.collection('students');
    callback(collection);
  });
};
迷茫迷茫2873일 전484

모든 응답(4)나는 대답할 것이다

  • 怪我咯

    怪我咯2017-04-17 15:40:05

    처리 프로세스는 실제로 비동기식입니다. 대부분의 언어/프레임워크에서는 기본적으로 동기식으로 처리됩니다. 비동기 처리가 필요한 경우 비동기 처리를 위해 스레드가 열리므로 비동기 처리 횟수를 쉽게 제어할 수 있습니다. 그러나 Node의 구현은 약간 다릅니다. JavaScript는 단일 스레드 프로그램이므로 방해를 피하기 위해 더 많은 시간이 소요되는 작업이 비동기식으로 처리됩니다.

    설명: 단일 스레드 비동기 작업은 설명하기가 어색합니다. 원칙에 대한 소개가 많이 있습니다. 기본 스레드가 UI를 담당하고 다른 모든 작업은 비동기적으로 수행되어야 한다는 점을 직접적으로 이해합니다. 다른 스레드에서. Android는 이 방향으로 발전하고 있으며 이미 네트워크 작업이 메인 스레드에서 수행되지 않도록 요구하므로 이 접근 방식은 이해할 수 있습니다.

    비동기 처리에는 메시지 알림 또는 스레드 간 상호 작용이 포함되어야 합니다. Node에서는 콜백을 통해 구현되거나(단일 스레드 비동기... 얽혀 있기 때문에), 더 우아하게 표현하면 관찰자 패턴을 통해 구현됩니다. ES5의 경우 콜백을 사용하여 콜백을 포함하는 것이 가장 간단한 방법입니다. 물론 Node가 점점 더 광범위하게 사용되면서 이 문제를 해결하기 위해 Promise 라이브러리라고 불리는 많은 라이브러리가 등장했습니다. 분명히 ECMA도 이 문제를 알고 있으므로 Promise 구현은 ES6/ES2015에 직접 내장됩니다.

    으아아아

    전화

    으아아아

    Promise를 사용하는 것이 훨씬 낫기는 하지만 여전히 작성하기가 상대적으로 번거롭습니다. 특히 사용된 라이브러리가 Promise와 함께 패키지되지 않은 경우 직접 수정하는 것은 고통스럽습니다.

    그래서 ES7은 비동기 호출을 동기화하기 위해 async/await 구현을 준비하고 있습니다(실제 동기화가 아닌 서면 동기화만 의미함). 또한 KOA와 같은 일부 라이브러리에서는 생성기를 통해 비동기 체인을 구현하려고 시도합니다. 자세한 내용은 KOA 문서를 참조하세요.

    회신하다
    0
  • PHP中文网

    PHP中文网2017-04-17 15:40:05

    1.asyncjs
    2.bluebird
    3. 노드 7.X가 출시될 때까지 기다리고 wait/async를 사용하세요

    회신하다
    0
  • PHP中文网

    PHP中文网2017-04-17 15:40:05

    이 문제는 node.js를 처음 접할 때 익숙해지기 어려울 수 있습니다. 예, 생각해보면 조립 라인처럼 실행되지만 기본 방법은 콜백 함수일 뿐입니다. 상자를 열고 실행하게 하세요. 그런 다음 원하는 것을 주세요. 이 상자에 넣으십시오). 그러나 콜백 함수는 다른 것을 실행하기 전에 실행될 때까지 기다리지 않으므로 순차적으로 결과를 얻을 수 없습니다. 쿼리가 실행되면 마지막 문장까지 즉시 다음 문장이 실행됩니다. 문장이므로 결과는 매번 동일합니다. 따라서 콜백 함수에서 다음 단계를 수행해야 하는데 앞으로는 너무 많은 단계가 깊게 중첩될 것임을 알게 될 것이며 promise generator 및 async await에 대해 배우게 될 것입니다.

    반환해야 하는 경우 콜백 함수를 수락한 다음 이 함수를 호출하여 데이터를 전송할 수 있습니다.

    당신의 예를 시각화해 보겠습니다.

    아버지께서 냄비를 주시고 간장을 사달라고 하셨습니다. 동생에게 간장을 사서 냄비에 넣어달라고 하신 후, 형이 돌아와서 간장을 만들어 달라고 하는 과정입니다. 간장을 만들고 나면 콜백 함수가 실행되고 다음 단계로 넘어갑니다. 이 과정을 염두에 두어야 하는데, 그냥 형에게 간장을 만들어달라고 부탁하고 아빠에게 냄비를 건넸습니다. 물론 기름통은 매번 비어있습니다.

    컴퓨터가 없으면 코드를 작성할 수 없습니다. 코드는 가장 직관적이어야 합니다.

    회신하다
    0
  • 天蓬老师

    天蓬老师2017-04-17 15:40:05

    반환된 데이터를 저장할 객체를 정의한 후 이 객체를 프런트 엔드에 반환합니다

    회신하다
    0
  • 취소회신하다