Javascript 函数的缓存结果

Javascript 函数的缓存结果,javascript,node.js,Javascript,Node.js,如何在节点的变量中存储异步函数的结果?例如,我想解析一个网站并获取一些信息,但我不想不断地请求数据,我只想获取所有页面一次。以下是代码: var cheerio = require('cheerio'); var request = require('request'); function SiteParser() { const SITE = 'http://www.anywebsite.com'; // variable for caching html var $ = ge

如何在节点的变量中存储异步函数的结果?例如,我想解析一个网站并获取一些信息,但我不想不断地请求数据,我只想获取所有页面一次。以下是代码:

var cheerio = require('cheerio');
var request = require('request');

function SiteParser() {
  const SITE = 'http://www.anywebsite.com';

  // variable for caching html
  var $ = getBody();

  function getBody(SITE){
    // request html
    request(SITE, function(error, response, html) {
      if (!error && response.statusCode == 200) {
        return cheerio.load(html);
      }
      else {
        throw new Error('Could not parse web site\nError text: ' + error);
      }
    })
  }

  //declaration of class methods using cached html
  this.getCategories = function() {};
  this.getNews = function() {};
}
当我调用类的方法时,我如何确定会收到响应?
或者这是一种不好的做法?

请注意
var$=getBody()getBody
不返回任何内容,因此code>不能按您的要求工作。它是返回某些内容的内部回调,但返回值永远丢失。此外,该回调是异步调用的,因此您无法通过
var$=getBody()获取它,因为
getBody
在执行回调之前完成

所以,这里有一个快速解决这个问题的方法。构造函数将可选回调函数作为参数:

function SiteParser(onready) {
  const SITE = 'http://www.anywebsite.com';

  // variable for caching html
  var $;
  var that = this; // maintain reference to this instance of SiteParser

  function getBody(SITE){
    // request html
    request(SITE, function(error, response, html) {
      if (!error && response.statusCode == 200) {
        $ = cheerio.load(html); // store the result
        that.ready() // notify client that html has been retrieved
      }
      else {
        throw new Error('Could not parse web site\nError text: ' + error);
      }
    })
  }

  //declaration of class methods using cached html
  this.getCategories = function() {
      if ($ === undefined) throw new Error('Not ready yet');
      // extract categories from $ and return them
  };
  this.getNews = function() {
      if ($ === undefined) throw new Error('Not ready yet');
      // extract news from $ and return it
  };
  this.ready = onready || function() {}; // callback for being notified
}
现在你可以写:

parser = new SiteParser;
parser.ready = function () {
    var cats = parser.getCategories();
    // ...etc
};
或者:

parser = new SiteParser(function () {
    var cats = parser.getCategories();
    // ...etc
});
允诺 上面的代码公开了getCategories和getNews方法,即使尚未检索HTML也是如此。这不太好

使用promise概念,您可以通过仅在一切就绪时提供SiteParser实例来改进这一点。以下是一些(未经测试的)代码,可用于:


请注意,
var$=getBody()getBody
不返回任何内容,因此code>不能按您的要求工作。它是返回某些内容的内部回调,但返回值永远丢失。此外,该回调是异步调用的,因此您无法通过
var$=getBody()获取它,因为
getBody
在执行回调之前完成

所以,这里有一个快速解决这个问题的方法。构造函数将可选回调函数作为参数:

function SiteParser(onready) {
  const SITE = 'http://www.anywebsite.com';

  // variable for caching html
  var $;
  var that = this; // maintain reference to this instance of SiteParser

  function getBody(SITE){
    // request html
    request(SITE, function(error, response, html) {
      if (!error && response.statusCode == 200) {
        $ = cheerio.load(html); // store the result
        that.ready() // notify client that html has been retrieved
      }
      else {
        throw new Error('Could not parse web site\nError text: ' + error);
      }
    })
  }

  //declaration of class methods using cached html
  this.getCategories = function() {
      if ($ === undefined) throw new Error('Not ready yet');
      // extract categories from $ and return them
  };
  this.getNews = function() {
      if ($ === undefined) throw new Error('Not ready yet');
      // extract news from $ and return it
  };
  this.ready = onready || function() {}; // callback for being notified
}
现在你可以写:

parser = new SiteParser;
parser.ready = function () {
    var cats = parser.getCategories();
    // ...etc
};
或者:

parser = new SiteParser(function () {
    var cats = parser.getCategories();
    // ...etc
});
允诺 上面的代码公开了getCategories和getNews方法,即使尚未检索HTML也是如此。这不太好

使用promise概念,您可以通过仅在一切就绪时提供SiteParser实例来改进这一点。以下是一些(未经测试的)代码,可用于:


请包括异步调用的代码。您也熟悉回调吗?@trincot async call只是使用request.js的简单http请求,这里真的有必要吗?@Rabee我知道,但我不知道如何在这种情况下使用它们。你是一般编程新手还是只熟悉JS?请包括异步调用的代码。你也熟悉回调吗?@trincot async call只是使用request.JS的简单http请求,这里真的有必要吗?@Rabee我知道,但我不知道如何在这种情况下使用它们。你是一般编程新手还是只熟悉JS?