SoFunction
Updated on 2025-03-03

Two implementation methods for Nodejs callback plus timeout limit

Two implementation methods for Nodejs callback plus timeout limit

The IO operations under Nodejs are all asynchronous. Sometimes the asynchronous request returns too slowly and you don’t want to wait for the callback infinitely? We can add a timeout limit to the callback function. If the callback has not yet reached a certain time, it means failure and continue with the subsequent steps.

Solution 1: Use async parallel to implement

Here I used the async parallel method. Parallel can enable several asynchronous callback methods to be executed in parallel. Under normal circumstances, all callback functions will be collected into the final callback function of parallel after completion. However, there is an exception. If one of the steps is thrown in error and the final callback function of parallel is called directly, we can use this feature to achieve the functions we want.

I encapsulated a function asyncWrapper, the logic is relatively simple, just look at the code:

const async = require('async');

const asyncWrapper = (fn, interval, ...args) =>{
  let final_callback = args[-1];
  ([
    function(callback){
      args[ - 1] = callback;
      (this, args);
    },
    function(callback){
      setTimeout(function(){
        callback(408);
      }, interval);
    }
  ],
  function(err, results){
    if(err==408 && results[0])err = null;
    final_callback.apply(this,[err].concat([results[0]]));
  });
}

if(){
   = asyncWrapper;
}else{
  let myfn = (arg_1, arg_2, callback) => {
    setTimeout(function(){
      callback(null,'value 1: '+arg_1,'value 2: '+arg_2);
    }, 1000);
  }
  asyncWrapper(myfn, 2000, 10, 20, (err, values)=>{
    (`${err}, ${values}`);
  });
}

You can run this js directly to see the effect:

node 

Module call method:

const asyncWrapper = require('./').asyncWrapper


const fn = (arg1, arg2, callback) => {
   //...Suppose the process is long and it may be timed out   callback(null, result_1, result_2);
}

asyncWrapper(
   fn,//Async function   10000,//Timeout time   'arg1_value',//Article 1 of the asynchronous function   'arg2_value',//Argument 2 of the asynchronous function, if there are multiple parameters, continue to add them later   (err, results)=>{
    //results : [result_1, result_2]
    //The last callback, results are quite special. When fn has multiple return values, results will be returned to you in an array form.   }
);

The advantage of this solution is that there is no minimum version requirement for node, so it can be used by introducing the async library. The flaw is that the final returned values ​​are presented in an array in a parameter.

Solution 2: Implementation with Promise

Add settimeout to promise and reject after the time is exceeded.

const promiseWrapper = (fn, interval, ...args) =>{
 let final_callback = args[-1];
 new Promise((resolve, reject)=>{
 args[ - 1] = (err, ...vals)=>{
  if(err)reject(err);
  else resolve(vals);
 };
    (this, args);
    setTimeout(_=>{
     reject('Promise time out');
    }, interval);
 })
 .then(
 result => {
  final_callback.apply(this, [null].concat(result));
 }
 )
  .catch(err=>{
   final_callback(err);
  })
}


if(){
   = promiseWrapper;
}else{
  let myfn = (arg_1, arg_2, callback) => {
    setTimeout(function(){
      callback(null,'value 1: '+arg_1,'value 2: '+arg_2);
    }, 1000);
  }
  promiseWrapper(myfn, 1000, 10, 20, (err, value_1, value_2)=>{
    (`${err}, value 1: ${value_1} ... value 2: ${value_2}`);
  });
}

Module call method:

const asyncWrapper = require('./').promiseWrapper


const fn = (arg1, arg2, callback) => {
   //...Suppose the process is long and it may be timed out   callback(null, result_1, result_2);
}

promiseWrapper(
   fn,//Async function   10000,//Timeout time   'arg1_value',//Article 1 of the asynchronous function   'arg2_value',//Argument 2 of the asynchronous function, if there are multiple parameters, continue to add them later   (err, result_1, result_2)=>{
    //The last callback   }
);

This solution requires nodejs version to be higher than 5.0 and supports Promise.

Thank you for reading, I hope it can help you. Thank you for your support for this site!