Using Nodejs to implement delay call and avoid closure problem of timed task

Source: Internet
Author: User

A lot of people are using Nodejs settimeout (callback, delay[, arg][, ...]) When writing timed tasks, it is customary to directly manipulate callback objects outside the object (characteristics of closures). There is a hidden danger that when callback is actually executing, the external object objects may have been destroyed (such as a custom destruction method), resulting in a great deal of deviation from the processing of object, and the program may even exit with an exception.

To solve this problem is very simple, we just need to retrieve the object in some way in the callback callback, check whether the object has been destroyed, can avoid the problem described above. However, when many of these requirements are needed in a program, and a team is working together to write code, it is difficult to avoid the situation. In order to avoid the closure problem of timed tasks, I wrote a deferred call class with the following code:

/** * script:delayCall.js * Description: Delayed call to circumvent the closure problem of timed tasks * Authors: [email protected] * date:2016-04-19 */var util = Require (' util '); var pqueue = require ('./pqueue '). pqueue;/** * Deferred Call class * @param Search_func object lookup function */var Delaycall = exports.    Delaycall = function (search_func) {//delay call ordinal this._call_seq = 0;    Deferred call mapping This._call_map = {};    Deferred call queue This._call_queue = new Pqueue (delaycall.compare);    Object Lookup Method This._search_func = Search_func; Set the interval timer.    Fixme: Can be changed in the framework of the heartbeat mechanism to execute the Run method//Note: SetTimeout does not support modifying the system time THIS._INTERVAL_ID = SetInterval (() = {This.run (); }, 1000);};/    /Compare delay Call Delaycall.compare = function (Call1, call2) {var time_diff = Call1.exec_time-call2.exec_time;    if (Time_diff) {return time_diff;    } else {return call1._call_id-call2._call_id; }};//Delay call sequence number self-increment delaycall.prototype._addsequence = function () {return + + this._call_seq;};/ * * Deferred call * @param ID Object Lookup method _search_func the caller object based on ID * @param method_name Caller ObjectThe method name to delay the call * @param params to delay the invocation of the method parameter * @param delay time, in seconds */delaycall.prototype.call = function (ID, method_name, params    , delay) {var call_id = this._addsequence ();    var exec_time = Date.now () + delay * 1000;        var Call_elem = {_call_id:call_id, id:id, Method_name:method_name, Params:params,    Delay:delay, Exec_time:exec_time, _canceled:false,};    This._call_queue.enqueue (Call_elem);    THIS._CALL_MAP[CALL_ID] = Call_elem; Return call_id;};/    /Cancel delay Call DelayCall.prototype.cancelCall = function (call_id) {var call_elem = this._call_map[call_id];        if (call_elem) {delete this._call_map[call_id];    Call_elem._canceled = true;    }};//Run Once DelayCall.prototype.run = function () {var now = Date.now ();    var pqueue = This._call_queue;    var search_func = This._search_func;    var Call_elem = Pqueue.gethead ();        while (Call_elem) {if (call_elem._canceled) {pqueue.dequeue (); } else {if (now < call_elem.exec_time) {break;                } else {//Remove Pqueue.dequeue () from queue and map;                Delete this._call_map[call_elem._call_id];                Method of executing the object var obj = Search_func (call_elem.id); if (obj && typeof obj[call_elem.method_name] = = ' function ') {Obj[call_elem.method_name] (call_e                Lem.params);    }}} Call_elem = Pqueue.gethead (); }};

Pqueue Implementation Please refer to my hungry Another blog post: Implementing priority queues with Nodejs Pqueue

Using Nodejs to implement delay call and avoid closure problem of timed task

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.