Я разрабатываю код внутреннего сервера с NodeJS. Что код делает, так это периодически подключается к REST API, запрашивает обновления и затем пишет в мою базу данных.

У меня нет возможности получить дельту данных из API, поэтому я отбрасываю свою коллекцию из MongoDB, а затем просто вставляю недавно извлеченные данные.

Я реализовал обещания, чтобы убедиться, что зависимые методы выполняются только после разрешения предыдущих методов. Это, однако, не работает, как я ожидал.

Итак, я сбрасываю коллекцию и вставляю, это работает. Но следующий метод, кажется, выполняется до заполнения новых данных. Иногда это работает, когда у меня есть несколько новых console.log операторов, которые, кажется, вызывают небольшую задержку, чтобы заставить все это работать.

Функция setTimeout, похоже, не помогла. Какие-либо предложения?

Вот исправленная версия кода: https://jsfiddle.net/ppbfrozg/

var request = require("request");
var q = require('q');

function authenticate() {
  var deferred = q.defer();
  request(options, function(error, response, body) {
    if (error) throw new Error(error);
    deferred.resolve(JSON.parse(body).token);
  });

  return deferred.promise;
}


function getData(token) {
  var deferred = q.defer();
  request(options, function(error, response, body) {
    if (error) throw new Error(error);
    deferred.resolve(JSON.parse(body).token);

  });

  return deferred.promise;
}


function insertDataInMongo(a) {
  var deferred = q.defer();
  var MongoClient = require('mongodb').MongoClient;
  var url = 'mongodb://localhost/myDB';
  var token = a[1];
  MongoClient.connect(url, function(err, db) {
    if (err) return deferred.reject(new Error(err))
    console.log("connected for insert");


    var apiData = JSON.parse(a[0]).data;

    if (JSON.parse(a[0]).data) {


      db.collection('MediaData').insert(apiData);
      console.log("Records Inserted");
    } else {

      db.collection('Details').drop();
      db.collection('Details').insert(JSON.parse(a[0]));

      console.log("Records Inserted");
    }

    deferred.resolve(token);

  });

  return deferred.promise;
}


function getMedia(dataContext) {

  var deferred = q.defer();

  var cursor = dataContext[0];
  var token = dataContext[1];

  if (cursor !== null) {
    console.log("Inside cursor not null");

    cursor.forEach(function(data) {
      insertDataInMongo(data);
    })
  }

  return deferred.promise;
}


function check(array, attr, value) {
  for (var i = 0; i < array.length; i += 1) {
    if (array[i][attr] === value) {
      return false;
    }
  }
  return true;
}

function get_value(array, attr) {
  for (var i = 0; i < array.length; i += 1) {
    if (array[i].hasOwnProperty(attr)) {
      return array[i][attr];
    }
  }
}


function getNames(token) {

  var deferred = q.defer();

  var MongoClient2 = require('mongodb').MongoClient;
  var url = 'mongodb://localhost/myDB';

  console.log("going to get Data");

  MongoClient2.connect(url, function(err, db) {
    if (err) return deferred.reject(new Error(err));
    console.log("connected for select");

    var data = db.collection('Details').find();
    var dataContext = [data, token, 0, 0, 0, 0, 0, 0, 0, null];

    deferred.resolve(dataContext);
  });
  return deferred.promise;
}


function convertDate(date) {
  var yyyy = date.getFullYear().toString();
  var mm = (date.getMonth() + 1).toString();
  var dd = (date.getDate() - 3).toString();

  var mmChars = mm.split('');
  var ddChars = dd.split('');

  return yyyy + '-' + (mmChars[1] ? mm : "0" + mmChars[0]) + '-' + (ddChars[1] ? dd : "0" + ddChars[0]);
}


authenticate()
  .then(getData)
  .then(insertDataInMongo)
  .then(getNames)
  .then(getMedia);
-1
SAS 24 Апр 2017 в 05:57

2 ответа

Лучший ответ

Это должно работать. Дайте мне знать, если возникнет проблема.

function insertDataInMongo(a) {
  var deferred = q.defer();
  var MongoClient = require('mongodb').MongoClient;
  var url = 'mongodb://localhost/myDB';
  var token = a[1];
  MongoClient.connect(url, function(err, db) {
    if (err) return deferred.reject(new Error(err))
    console.log("connected for insert");

    var apiData = JSON.parse(a[0]).data;
    if (JSON.parse(a[0]).data) {
      db.collection('MediaData').insert(apiData, function(){
        console.log("Records Inserted");
        return deferred.resolve(token);
      });
    } else {
      db.collection('Details').drop(function(error, result){//Callback function that executes after drop operation has completed.
        if(error){
          return deferred.reject(error);//Reject the promise if there was an error
        }
        db.collection('Details').insert(JSON.parse(a[0]), function(err, res){//Callback function that executes after insert operation has completed.
          if(err){
            return deferred.reject(err);//Reject the promise if there was an error
          }
          console.log("Records Inserted");
          return deferred.resolve(token);
        });
      });
    }
  });
  return deferred.promise;
}
0
Hannan 24 Апр 2017 в 03:58

Из того, что я вижу из API драйвера nodeJS для MongoDB: https://mongodb.github.io/node-mongodb- родной / API -порожденный / collection.html

Подсказка: db.collection.drop асинхронный, поэтому вы должны использовать обратный вызов с ним

db.collection('Details').drop(function(err, result){
    // Do anything AFTER you dropped your collection
}

Но так как вы используете обещания, вы должны использовать что-то вроде этого:

authenticate()
.then(getData)
.then(db.collection('Details').drop)
.then(insertDataInMongo)
.then(getNames)
.then(getMedia);

Или если вы действительно хотите сохранить тот же формат кода:

function dropCollectionInMongo() {
    db.collection('Details').drop()
}
authenticate()
.then(getData)
.then(dropCollectionInMongo)
.then(insertDataInMongo)
.then(getNames)
.then(getMedia);
0
Amine 24 Апр 2017 в 13:50