node.js超时未触发

时间:2016-04-23 09:34:14

标签: javascript node.js settimeout x-ray

我使用x-ray库抓取特定网站的某些内容并将其保存在JSON文件中。

我想每小时获取一次状态,但Node不会执行我的setTimeout

这是我的代码:

var db, record, x;
x = require('x-ray')();
db = require('lowdb')('rec.json', {
  storage: require('lowdb/file-async')
});

record = function() {
  console.log('will contact server');
  setTimeout(record, 60 * 60 * 1000);
  x('http://example.com', 'h1')(function(err, content) {
    console.log('server contacted');
    if (err) {
      console.log('error occurred');
      db('status').push({
        time: (new Date).toString(),
        status: err
      });
    } else {
      console.log('status recorded successfully');
      db('status').push({
        time: (new Date).toString(),
        status: content
      });
    }
  });
};
console.log('ready');

record();

它首次记录没有任何问题,但在此之后,它什么也没做。似乎record函数只执行一次。

我使用pm2来管理流程,pm2 list表明它的运行时间超过了60分钟。即使Node无法在给定时间内完全执行回调,该过程仍然存在(最长时间,在我重新启动之前)大约80分钟。

日志中没有错误,我的测试期间没有意外重启。

也许这与我正在使用的图书馆有关?我想出了可能造成这种情况的想法。

2 个答案:

答案 0 :(得分:0)

来自LowDB Docs

  

重要

     

修改数据库时,将返回Promise。

     

当您从数据库中读取数据时,会立即返回结果。

调度then回调中的函数执行应该有效:

var db, record, x;
x = require('x-ray')();
db = require('lowdb')('rec.json', {
  storage: require('lowdb/file-async')
});

record = function() {
  console.log('will contact server');
  x('http://example.com', 'h1')(function(err, content) {
    console.log('server contacted');
    if (err) {
      console.log('error occurred');
      db('status').push({
        time: (new Date).toString(),
        status: err
      }).then(function(status) {
        setTimeout(record, 60 * 60 * 1000);
      });
    } else {
      console.log('status recorded successfully');
      db('status').push({
        time: (new Date).toString(),
        status: content
      }).then(function(status) {
        setTimeout(record, 60 * 60 * 1000);
      });
    }
  });
};
console.log('ready');

record();

答案 1 :(得分:0)

虽然不是一个确切的解决方案,但我将此作为答案发布,因为它解决了这个问题,并且也关闭了这个问题。

最终,我使用cron解决了这个问题。