2016-04-09 10 views
1

У меня есть небольшая проблема с mongoose, то, что я делаю, это получение данных из онлайн-кормов rss, их разбор и передача его в массив, из которого я кормлю модель mongoose, и все это происходит на маршруте получения, что я хочу выполнить, это удалить все данные сначала из модели mongoose, а затем заполнить их новыми данными, но он всегда либо удаляет данные все вместе, так как парсер выполняет итерацию несколько раз, или он ничего не удаляет, и данные просто продолжают добавлять к модели.Mongoose удалить и создать в полете

Вот мой код

'use strict'; 
const Promise = require('bluebird'); 
const request = require('request'); 
const FeedParser = require('feedparser'); 
const express = require('express'); 
const router = express.Router(); 
const xray = require('x-ray')(); 
var Post = require('../models/post'); 
var dataArray = []; 

router.get('/', function (req, res) { 

    const fetch = (url) => { 

     return new Promise((resolve, reject) => { 
      if (!url) { 
       return reject(new Error(`Bad URL (url: ${url}`)); 
      } 

      const feedparser = new FeedParser(); 
      const items = []; 

      feedparser.on('error', (e) => { 
       return reject(e); 
      }).on('readable',() => { 
       // This is where the action is! 
       var item; 
       console.time('loading') 
       while (item = feedparser.read()) { 
        items.push(item); 
       } 
      }).on('end',() => { 
       resolve({ 
        meta: feedparser.meta, 
        records: items 
       }); 
      }); 

      request({ 
       method: 'GET', 
       url: url 
      }, (e, res, body) => { 
       if (e) { 
        return reject(e); 
       } else if (res.statusCode != 200) { 
        return reject(new Error(`Bad status code (status: ${res.statusCode}, url: ${url})`)); 
       } 
       feedparser.end(body); 
       feedparser.on('end', function() { 
        console.log('Done'); 
       }); 
      }); 
     }); 
    }; 

    Promise.map([ 
      'url', 
      'url',        
      'url', 
      'url'], (url) => fetch(url), { concurrency: 4 }) // note that concurrency limit 
     .then((feeds) => { 
      feeds.forEach(feed => { 
       feed.records.forEach(record => { 
        dataArray.push(record); 
       }); 
      }); 
     }).catch(function (error) { 
      console.log(error); 
     }); 

    Post.remove({}, function (err) { 
     if (err) { 
      console.log(err); 
     } else { 
      console.log('collection removed'); 
     } 
    }); 

    dataArray.forEach(post => { 
     Post.create({ 
      title: post.title, 
      content: post.description, 
      created: post.date, 
      image: post['rss:image']['#'], 
      link: post.link 
     }, function (err, newPost) { 
      console.log(newPost.title); 
     }); 
    }); 
    Post.find({}, function (err, posts) { 
     if (err) { 
      console.log(err); 
     } else { 
      res.render('index/home', { 
       posts: posts 
      }); 
     } 
    }); 
}); 


module.exports = router; 

ответ

1

Ничего из этого не будет работать синхронно. Вы можете сделать что-то вроде этого:

'use strict'; 
const Promise = require('bluebird'); 
const request = require('request'); 
const FeedParser = require('feedparser'); 
const express = require('express'); 
const router = express.Router(); 
const xray = require('x-ray')(); 
var Post = require('../models/post'); 
var dataArray = []; 
const fetch; 

router.get('/', function (req, res) { 

Post.remove({}, function (err) { 
    if (err) { 
     console.log(err); 
    } else { 
     console.log('collection removed. Starting to fetch Posts from Service'); 
     fetch = (url) => { 
      return new Promise((resolve, reject) => { 
       if (!url) { 
        return reject(new Error(`Bad URL (url: ${url}`)); 
       } 

       const feedparser = new FeedParser(); 
       const items = []; 

       feedparser.on('error', (e) => { 
        return reject(e); 
       }).on('readable',() => { 
        // This is where the action is! 
        var item; 
        console.time('loading') 
        while (item = feedparser.read()) { 
         items.push(item); 
        } 
       }).on('end',() => { 
        resolve({ 
         meta: feedparser.meta, 
         records: items 
        }); 
       }); 

       request({ 
        method: 'GET', 
        url: url 
       }, (e, res, body) => { 
        if (e) { 
         return reject(e); 
        } else if (res.statusCode != 200) { 
         return reject(new Error(`Bad status code (status: ${res.statusCode}, url: ${url})`)); 
        } 
        feedparser.end(body); 
        feedparser.on('end', function() { 
         console.log('Done'); 
        }); 
       }); 
      }); 
     }; 
    } 
}); 

Promise.map([ 
     'url', 
     'url',        
     'url', 
     'url'], (url) => fetch(url), { concurrency: 4 }) // note that concurrency limit 
    .then((feeds) => { 
     feeds.forEach(feed => { 
      dataArray = dataArray.concat(feed.records); 
      /*feed.records.forEach(record => { 
       dataArray.push(record); 
      });*/ 
     }); 
     console.log('inserting posts in the collection'); 
     dataArray.forEach(post => { 
      Post.create({ 
       title: post.title, 
       content: post.description, 
       created: post.date, 
       image: post['rss:image']['#'], 
       link: post.link 
      }, function (err, newPost) { 
       console.log(newPost.title); 
      }); 
     }); 

     console.log("Fetching posts from the collection"); 
     Post.find({}, function (err, posts) { 
      if (err) { 
       console.log(err); 
      } else { 
       res.render('index/home', { 
        posts: posts 
       }); 
      } 
     }); 

    }).catch(function (error) { 
     console.log(error); 
    }); 
}); 


module.exports = router; 

Я не тестировал это. Пожалуйста, проверьте это на своем конце. Дайте мне знать, есть ли ошибка или что-то в этом роде.

+0

Не могли бы вы рассказать о событии? Я попробовал ваше решение, но он по-прежнему делает то же самое, о котором я говорил первоначально, он просто добавляет коллекцию каждый раз, когда я обновляюсь. То, что я пытаюсь выполнить, - это просто удалить все данные, а затем добавить его снова после Promise.map, все, что должно произойти после обновления страницы. –

+0

Вам нужно сначала удалить элементы из коллекции 'Post', затем воспользоваться службой и получить данные сообщений, а затем добавить данные в коллекцию' Post'? Coz прямо сейчас мы сначала извлекаем данные из службы, а затем удаляем все сообщения из коллекции 'Post', а затем добавляем в нее сообщения. –

+0

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

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