MeteorJS:回调

MeteorJS: CALLBACKS

问题: 我想解析来自另一个网站的页面中的元素,将生成的元素粘合到一个对象中并将其插入到 Mongo 集合中。在插入之前,我想检查我的 Mongo 是否有相同的对象。如果是,它将退出 运行 函数,否则我希望脚本开始解析下一个目标。

示例:

  1. 我有一个连接到网页的功能,returns它的body内容
  2. 已解析
  3. 当遇到<a></a>个元素时,调用另一个回调,将所有解析的元素合并到一个对象中并插入到集合中

我的代码:

var Cheerio  = Meteor.npmRequire('cheerio');
var lastUrl;
var exit = false;
Meteor.methods({
  parsing:function(){
    this.unblock();
    request("https://example.com/", Meteor.bindEnvironment(function(error, response, body) {
      if (!error && response.statusCode == 200) {
        $ = Cheerio.load(body);
        var k = 1;
        $("div.content").each(function() {
          var name = $...//parsing
          var age = $....//parsing
          var url = $...//parsing <a></a> elements
          var r = request("https://example.com/"+url, Meteor.bindEnvironment(function(error, response, body) {
            lastUrl = response.request.uri.href;// get the last routing link
            var metadata = {
              name: name,
              age: age
              url: lastUrl
            };
            var postExist;
            postExist = Posts.findOne(metadata); // return undefined if doesnt exist, AND every time postExist = undefined ??
            if (!postExist){
              Posts.insert(metadata);// if post doesnt exist (every time go here ??)
            }
            else {
              exit = true; // if exist
            }
          }));
          if (exit === true) return false;
        });
      }
  }));
}
});

问题 1 :问题是我的函数每次都有效,但即使对象存在于我的集合中它也不会停止

问题 2: postExist 始终未定义

编辑: 执行必须停止并等待第二个请求的响应。

var url = $...//parsing <a></a> elements 

//STOP HERE AND WAIT !!

var r = request("https://example.com/"+url, Meteor.bindEnvironment(function(error, response, body) {

这是相反的:

postExist = Posts.findOne(metadata); // return undefined if doesnt exist > you're right
if (!postExist){ //=if NOT undefined = if it EXISTS !
    Posts.insert(metadata);
}else {
    exit = true; // if undefined > if it DOES NOT EXIST !
}

你需要把条件或者里面的代码倒过来

您似乎希望第二个请求是同步的而不是异步的。

要实现这一点,请使用 future

var Cheerio  = Meteor.npmRequire('cheerio');
var Future = Meteor.npmRequire('fibers/future');
var lastUrl;
var exit = false;
Meteor.methods({
  parsing:function(){
    this.unblock();
    request("https://example.com/", Meteor.bindEnvironment(function(error, response, body) {
      if (!error && response.statusCode == 200) {
        $ = Cheerio.load(body);
        var k = 1;
        $("div.content").each(function() {
          var name = $...//parsing
          var age = $....//parsing
          var url = $...//parsing <a></a> elements
          var fut = new Future();
          var r = request("https://example.com/"+url, Meteor.bindEnvironment(function(error, response, body) {
            lastUrl = response.request.uri.href;// get the last routing link
            var metadata = {
              name: name,
              age: age
              url: lastUrl
            };
            var postExist;
            postExist = Posts.findOne(metadata); // return undefined if doesnt exist
            if (!postExist) {
              Posts.insert(metadata);// if post doesnt exist (every time go here ??)
              fut.return(true);
            } else {
              fut.return(false);
            }
          }));
          var status = fut.wait();
          return status;
        });
      }
    }));
  }
});

您可以在无法使用回调函数时使用 futures(例如,您希望用户在显示信息之前等待回调的结果)。

希望对您有所帮助,

埃利奥特