Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 在何处存储我的节点计划_Node.js_Express_Scheduled Tasks - Fatal编程技术网

Node.js 在何处存储我的节点计划

Node.js 在何处存储我的节点计划,node.js,express,scheduled-tasks,Node.js,Express,Scheduled Tasks,我对Node/Express非常陌生,我正在制定预约系统。我希望我的用户在他们想要的日期预约,我的系统会在那个确切的时间向他们发送通知。我找到了“节点调度”模块,它非常适合这个任务,但我不知道在哪里实现它。在我的app.js中是否有存储所有任务的方法,或者每次到达某个端点时只创建一个节点调度任务就足够了,例如: router.get('/', function(req, res, next) { var j = schedule.scheduleJob(date, function(){

我对Node/Express非常陌生,我正在制定预约系统。我希望我的用户在他们想要的日期预约,我的系统会在那个确切的时间向他们发送通知。我找到了“节点调度”模块,它非常适合这个任务,但我不知道在哪里实现它。在我的app.js中是否有存储所有任务的方法,或者每次到达某个端点时只创建一个节点调度任务就足够了,例如:

router.get('/', function(req, res, next) {
 var j = schedule.scheduleJob(date, function(){
   send notification();
});
res.send(200);
}
  'use strict';
  
  var scheduler = require('node-schedule');

  /**
   * Storable Representation of a Scheduled Event
   *
   * @param {string|Date} when
   * @param {string} what
   * @param {array.<string>} [args=[]]
   * @param {boolean} [pending=true]
   *
   * @property {Date} PersistentEvent.when       - the datetime this event should fire.
   * @property {string} PersistentEvent.what     - the name of the action to run (must match key of PersistentEvent.Actions)
   * @property {array} PersistentEvent.args      - args to pass to action event handler.
   * @property {boolean} PersistentEvent.pending - if true, this event has not yet fired.
   *
   * @constructor
   *
   * @example
   *
   * var PersistentEvent = require('PersistentEvent'),
   *     mysql = require('mysql'),
   *     conn = mysql.createConnection({ ... });
   *
   * conn.connect();
   *
   * // at some point when initializing your app...
   *
   * // assign your persistent storage connection...
   * PersistentEvent.setStore(conn);
   *
   * // load all pending event from persistent storage...
   * PersistentEvent.loadAll$(function (err) {
   *   if (err) {
   *     throw new Error('failed to load all PersistentEvents: ' + err);
   *   }
   *
   *   // from this point on, all persistent events are loaded and running.
   *
   * });
   */
  var PersistentEvent = function (when, what, args, pending) {
    // initialize
    PersistentEvent.Cache.push(this.init({
      when: when,
      what: what,
      args: args,
      pending: pending
    }));
  };
  
  // ==== PersistentEvent Static Methods ====
  
  /**
   * Pre-defined action event handlers.
   * <p>
   * Where the property key will be used to match the PersistentEvent.what property,
   * and the property value is a event handler function that accepts an optional
   * array of args and a callback (provided by PersistentEvent.prototype.schedule)
   * </p>
   *
   * @property {object}
   * @property {function} Actions.doSomething
   * @property {function} Actions.doSomethingElse
   *
   * @static
   */
  PersistentEvent.Actions = {
    doSomething: function (args, cb) {
      // defaults
      args = args || [];
  
      // TODO check specific args here ...
  
      var result = true,
          err = null;
  
      // do your action here, possibly with passed args
  
      cb(err, result);
    },
    doSomethingElse: function (args, cb) {
      // defaults
      args = args || [];
  
      // TODO check specific args here ...
  
      var result = true,
          err = null;
  
      // do your action here, possibly with passed args
  
      cb(err, result);
    }
  };
  
  /**
   * Cache of all PersistentEvents
   *
   * @type {Array.<PersistentEvent>}
   * @static
   */
  PersistentEvent.Cache = [];
  
  // Data Management
  
  /**
   * Connection to persistent storage.
   * TODO - This should be abstracted to handle other engines that MySQL.
   * @property {object}
   * @static
   */
  PersistentEvent.StorageConnection = null;
  
  /**
   * Sets the storage connection used to persist events.
   *
   * @param {object} storageConnection
   * @static
   */
  PersistentEvent.setStore = function (storageConnection) { // set the persistent storage connection
                                                            // TODO - check args here...
  
    // Note: this function isn't really needed unless you're using other kinds of storage engines
    // where you'd want to test what engine was used and mutate this interface accordingly.
  
    PersistentEvent.StorageConnection = storageConnection;
  };
  
  /**
   * Saves a PersistentEvent to StorageConnection.
   *
   * @param {PersistentEvent} event - event to save
   * @param {function} cb - callback on complete
   * @static
   */
  PersistentEvent.save$ = function (event, cb) {
    var conn = PersistentEvent.StorageConnection;
  
    if (null === conn) {
      throw new Error('requires a StorageConnection');
    }
  
    // TODO - check for active connection here...
  
    // TODO - check args here...
  
    conn.query('INSERT INTO TABLE when = :when, what = :what, args = :args, pending = :pending', event, cb);
  };
  
  /**
   * Loads all PersistentEvents from StorageConnection.
   * @param {function} cb -- callback on complete
   * @static
   */
  PersistentEvent.loadAll$ = function (cb) {
    var conn = PersistentEvent.StorageConnection;
  
    if (null === conn) {
      throw new Error('requires a StorageConnection');
    }
  
    // check for active connection here...
  
    // check args here...
  
    conn.query('QUERY * FROM TABLE WHERE pending = true', function (err, results) {
      if (err) {
        return cb(err);
      }
      results.forEach(function (result) {
        // TODO: check for existence of required fields here...
        var event = new PersistentEvent(result.when, result.what, result.args, true);
        event.schedule();
      });
      cb(null);
    });
  };
  
  // ==== PersistentEvent Methods ====
  
  /**
   * Initialize an instance of PersistentEvent.
   *
   * @param {object} opts
   * @return {PersistentEvent}
   */
  Event.prototype.init = function (opts) {
    // check args
    if ('object' !== typeof opts) {
      throw new Error('opts must be an object');
    }
  
    // set defaults
    opts.args = opts.args || [];
    opts.pending = opts.pending || true;
  
    // convert string to Date, if required
    if ('string' === typeof opts.when) {
      opts.when = new Date(opts.when);
    }
  
    // check that opts contains needed properties
    if (!opts.when instanceof Date) {
      throw new Error('when must be a string representation of a Date or a Date object');
    }
  
    if ('string' !== typeof opts.what) {
      throw new Error('what must be a string containing an action name');
    }
  
    if (!Array.isArray(opts.args)) {
      throw new Error('args must be an array');
    }
  
    if ('boolean' !== typeof opts.pending) {
      throw new Error('pending must be a boolean');
    }
  
    // set our properties
    var self = this;
    Object.keys(opts).forEach(function (key) {
      if (opts.hasOwnProperty(key)) {
        self = opts[key];
      }
    });
  
    return this;
  };
  
  /**
   * Override for Object.toString()
   * @returns {string}
   */
  PersistentEvent.prototype.toString = function () {
    return JSON.stringify(this);
  };
  
  /**
   * Schedule the event to run.<br/>
   * <em>Side-effect: saves event to persistent storage.</em>
   */
  PersistentEvent.prototype.schedule = function () {
    var self = this,
        handler = Actions[this.what];
  
    if ('function' !== typeof handler) {
      throw new Error('no handler found for action:' + this.what);
    }
  
    PersistentEvent.save$(self, function () {
      self._event = scheduler.scheduleJob(self.when, function () {
        handler(self.args, function (err, result) {
          if (err) {
            console.error('event ' + self + ' failed:' + err);
          }
          self.setComplete();
        });
  
      });
    });
  };
  
  /**
   * Sets this event complete.<br/>
   * <em>Side-effect: saves event to persistent storage.</em>
   */
  PersistentEvent.prototype.setComplete = function () {
    var self = this;
    delete this._event;
    this.pending = false;
    PersistentEvent.save$(this, function (err) {
      if (err) {
        console.error('failed to save event ' + self + ' :' + err);
      }
    });
  };

注意:我不想在我的sql表上运行常量for循环来检查日期

您需要将应用程序数据持久化到某种形式的永久存储中,方法是使用类似的方式写入本地文件、运行您自己的数据库服务器(like)或使用基于云的存储服务(like)

这些选项中的每一个(以及许多其他选项)都有npm模块,可用于读取/写入/删除持久数据。有关示例,请参阅和,所有这些都可以使用上的
npm

更新 根据您在下面的评论:好吧,您确实问过您可以将预定的活动存储在哪里。;)

要持久化所有计划的事件,以便它们在可能的服务器故障中生存,您需要创建一个可存储的数据结构来表示它们,并为每个事件创建一个表示的新实例,并将其存储到持久存储(MySQL)中

通常,您会使用以下内容:

{
  when:DateTime        -- timestamp when the event should fire
  what:Action          -- what this event should do
  args:Arguments       -- arguments to pass to Action
  pending:Boolean=true -- if false, this event has already fired
}
初始化服务器时,您将查询持久存储中所有
pending===true
的事件,并使用结果初始化
节点调度
模块的实例

当您需要在服务器运行时计划新事件时,您需要创建一个新的事件表示,将其写入持久性存储,并使用它创建一个新的
节点计划实例

最后,也是对客户满意度最重要的一点,当计划的事件成功完成时,就在您的事件处理程序(上面提到的
操作
完成之前,它需要将正在处理的事件的持久版本标记为
挂起:false
,这样您就不会多次触发任何事件

例如:

router.get('/', function(req, res, next) {
 var j = schedule.scheduleJob(date, function(){
   send notification();
});
res.send(200);
}
  'use strict';
  
  var scheduler = require('node-schedule');

  /**
   * Storable Representation of a Scheduled Event
   *
   * @param {string|Date} when
   * @param {string} what
   * @param {array.<string>} [args=[]]
   * @param {boolean} [pending=true]
   *
   * @property {Date} PersistentEvent.when       - the datetime this event should fire.
   * @property {string} PersistentEvent.what     - the name of the action to run (must match key of PersistentEvent.Actions)
   * @property {array} PersistentEvent.args      - args to pass to action event handler.
   * @property {boolean} PersistentEvent.pending - if true, this event has not yet fired.
   *
   * @constructor
   *
   * @example
   *
   * var PersistentEvent = require('PersistentEvent'),
   *     mysql = require('mysql'),
   *     conn = mysql.createConnection({ ... });
   *
   * conn.connect();
   *
   * // at some point when initializing your app...
   *
   * // assign your persistent storage connection...
   * PersistentEvent.setStore(conn);
   *
   * // load all pending event from persistent storage...
   * PersistentEvent.loadAll$(function (err) {
   *   if (err) {
   *     throw new Error('failed to load all PersistentEvents: ' + err);
   *   }
   *
   *   // from this point on, all persistent events are loaded and running.
   *
   * });
   */
  var PersistentEvent = function (when, what, args, pending) {
    // initialize
    PersistentEvent.Cache.push(this.init({
      when: when,
      what: what,
      args: args,
      pending: pending
    }));
  };
  
  // ==== PersistentEvent Static Methods ====
  
  /**
   * Pre-defined action event handlers.
   * <p>
   * Where the property key will be used to match the PersistentEvent.what property,
   * and the property value is a event handler function that accepts an optional
   * array of args and a callback (provided by PersistentEvent.prototype.schedule)
   * </p>
   *
   * @property {object}
   * @property {function} Actions.doSomething
   * @property {function} Actions.doSomethingElse
   *
   * @static
   */
  PersistentEvent.Actions = {
    doSomething: function (args, cb) {
      // defaults
      args = args || [];
  
      // TODO check specific args here ...
  
      var result = true,
          err = null;
  
      // do your action here, possibly with passed args
  
      cb(err, result);
    },
    doSomethingElse: function (args, cb) {
      // defaults
      args = args || [];
  
      // TODO check specific args here ...
  
      var result = true,
          err = null;
  
      // do your action here, possibly with passed args
  
      cb(err, result);
    }
  };
  
  /**
   * Cache of all PersistentEvents
   *
   * @type {Array.<PersistentEvent>}
   * @static
   */
  PersistentEvent.Cache = [];
  
  // Data Management
  
  /**
   * Connection to persistent storage.
   * TODO - This should be abstracted to handle other engines that MySQL.
   * @property {object}
   * @static
   */
  PersistentEvent.StorageConnection = null;
  
  /**
   * Sets the storage connection used to persist events.
   *
   * @param {object} storageConnection
   * @static
   */
  PersistentEvent.setStore = function (storageConnection) { // set the persistent storage connection
                                                            // TODO - check args here...
  
    // Note: this function isn't really needed unless you're using other kinds of storage engines
    // where you'd want to test what engine was used and mutate this interface accordingly.
  
    PersistentEvent.StorageConnection = storageConnection;
  };
  
  /**
   * Saves a PersistentEvent to StorageConnection.
   *
   * @param {PersistentEvent} event - event to save
   * @param {function} cb - callback on complete
   * @static
   */
  PersistentEvent.save$ = function (event, cb) {
    var conn = PersistentEvent.StorageConnection;
  
    if (null === conn) {
      throw new Error('requires a StorageConnection');
    }
  
    // TODO - check for active connection here...
  
    // TODO - check args here...
  
    conn.query('INSERT INTO TABLE when = :when, what = :what, args = :args, pending = :pending', event, cb);
  };
  
  /**
   * Loads all PersistentEvents from StorageConnection.
   * @param {function} cb -- callback on complete
   * @static
   */
  PersistentEvent.loadAll$ = function (cb) {
    var conn = PersistentEvent.StorageConnection;
  
    if (null === conn) {
      throw new Error('requires a StorageConnection');
    }
  
    // check for active connection here...
  
    // check args here...
  
    conn.query('QUERY * FROM TABLE WHERE pending = true', function (err, results) {
      if (err) {
        return cb(err);
      }
      results.forEach(function (result) {
        // TODO: check for existence of required fields here...
        var event = new PersistentEvent(result.when, result.what, result.args, true);
        event.schedule();
      });
      cb(null);
    });
  };
  
  // ==== PersistentEvent Methods ====
  
  /**
   * Initialize an instance of PersistentEvent.
   *
   * @param {object} opts
   * @return {PersistentEvent}
   */
  Event.prototype.init = function (opts) {
    // check args
    if ('object' !== typeof opts) {
      throw new Error('opts must be an object');
    }
  
    // set defaults
    opts.args = opts.args || [];
    opts.pending = opts.pending || true;
  
    // convert string to Date, if required
    if ('string' === typeof opts.when) {
      opts.when = new Date(opts.when);
    }
  
    // check that opts contains needed properties
    if (!opts.when instanceof Date) {
      throw new Error('when must be a string representation of a Date or a Date object');
    }
  
    if ('string' !== typeof opts.what) {
      throw new Error('what must be a string containing an action name');
    }
  
    if (!Array.isArray(opts.args)) {
      throw new Error('args must be an array');
    }
  
    if ('boolean' !== typeof opts.pending) {
      throw new Error('pending must be a boolean');
    }
  
    // set our properties
    var self = this;
    Object.keys(opts).forEach(function (key) {
      if (opts.hasOwnProperty(key)) {
        self = opts[key];
      }
    });
  
    return this;
  };
  
  /**
   * Override for Object.toString()
   * @returns {string}
   */
  PersistentEvent.prototype.toString = function () {
    return JSON.stringify(this);
  };
  
  /**
   * Schedule the event to run.<br/>
   * <em>Side-effect: saves event to persistent storage.</em>
   */
  PersistentEvent.prototype.schedule = function () {
    var self = this,
        handler = Actions[this.what];
  
    if ('function' !== typeof handler) {
      throw new Error('no handler found for action:' + this.what);
    }
  
    PersistentEvent.save$(self, function () {
      self._event = scheduler.scheduleJob(self.when, function () {
        handler(self.args, function (err, result) {
          if (err) {
            console.error('event ' + self + ' failed:' + err);
          }
          self.setComplete();
        });
  
      });
    });
  };
  
  /**
   * Sets this event complete.<br/>
   * <em>Side-effect: saves event to persistent storage.</em>
   */
  PersistentEvent.prototype.setComplete = function () {
    var self = this;
    delete this._event;
    this.pending = false;
    PersistentEvent.save$(this, function (err) {
      if (err) {
        console.error('failed to save event ' + self + ' :' + err);
      }
    });
  };
“严格使用”;
var调度程序=require('node-schedule');
/**
*计划事件的可存储表示
*
*@param{string | Date}当
*@param{string}什么
*@param{array.}[args=[]
*@param{boolean}[pending=true]
*
*@property{Date}PersistentEvent.when-此事件应触发的日期时间。
*@property{string}PersistentEvent.what-要运行的操作的名称(必须与PersistentEvent.Actions的键匹配)
*@property{array}PersistentEvent.args-要传递给操作事件处理程序的args。
*@property{boolean}PersistentEvent.pending-如果为true,则此事件尚未激发。
*
*@constructor
*
*@example
*
*var PersistentEvent=require('PersistentEvent'),
*mysql=require('mysql'),
*conn=mysql.createConnection({…});
*
*连接();
*
*//在初始化应用程序时的某个时刻。。。
*
*//分配您的持久存储连接。。。
*持久事件设置存储(conn);
*
*//从持久性存储加载所有挂起事件。。。
*PersistentEvent.loadAll$(函数(错误){
*如果(错误){
*抛出新错误('未能加载所有PersistentEvents:'+错误);
*   }
*
*//从这一点开始,所有持久事件都将加载并运行。
*
* });
*/
var PersistentEvent=函数(何时、何时、参数、挂起){
//初始化
PersistentEvent.Cache.push(this.init({
什么时候,,
什么:什么,
args:args,
待定:待定
}));
};
//==持久事件静态方法====
/**
*预定义的操作事件处理程序。
*
*属性键将用于匹配PersistentEvent的位置。什么属性,
*属性值是一个接受可选
*参数数组和回调(由PersistentEvent.prototype.schedule提供)
*

* *@property{object} *@property{function}Actions.doSomething *@property{function}Actions.doSomethingElse * *@静态 */ PersistentEvent.Actions={ 剂量测量:功能(参数、cb){ //默认值 args=args | |[]; //TODO检查此处的特定参数。。。 var结果=真, err=null; //在这里执行您的操作,可能使用传递的参数 cb(错误、结果); }, doSomethingElse:函数(args、cb){ //默认值 args=args | |[]; //TODO检查此处的特定参数。。。 var结果=真, err=null; //在这里执行您的操作,可能使用传递的参数 cb(错误、结果); } }; /** *所有PersistentEvents的缓存 * *@type{Array.} *@静态 */ PersistentEvent.Cache=[]; //数据管理 /** *连接到持久存储。 *TODO-这应该被抽象为处理MySQL支持的其他引擎。 *@property{object} *@静态 */ PersistentEvent.StorageConnection=null; /** *设置用于持久化事件的存储连接。 * *@param{object}storageConnection *@静态 */ PersistentEvent.setStore=函数(storageConnection){//设置持久存储连接 //待办事项-检查此处的参数。。。 //注意:除非您使用其他类型的存储引擎,否则实际上不需要此功能 //您需要测试使用了什么引擎,并相应地修改此接口。 PersistentEvent.StorageConnection=存储连接; }; /** *将PersistentEvent保存到StorageConnection。 * *@param{PersistentEvent}event-要保存的事件 *@param{function}cb-完成时回调 *@静态 */ PersistentEvent.save$=函数(事件,cb){