Javascript Promise().然后防止在执行第一个调用之前重新调用该函数

Javascript Promise().then to prevent re-calling the function before the first call be executed

本文关键字:调用 函数 新调用 执行 然后 Promise Javascript 第一个      更新时间:2023-09-26

在我的node.js应用程序中,使用乏味的方法从MSSQL读取数据,我每1秒调用一次以下命令:

  1. 从服务器获取数据(fetchStock函数)并将其保存在临时数组中
  2. 使用Server-Sent Events(SSE)API将保存在临时阵列中的数据发送到客户端

在上一个调用完全执行之前,1秒似乎不足以调用fetchStock函数,所以我不时会收到执行错误。我把它增加到了5秒,但仍然每隔一段时间就会遇到同样的问题。

如何使用Promise().then来确保在前一个调用完全执行之前不会重新调用fetchStock函数?

var Request = require('tedious').Request;
var Connection = require('tedious').Connection;
var config = {
     userName: 'sa',
     password: 'pswd',
    server: 'xx.xxx.xx.xxx',
    options: {
        database: 'DB',
             rowCollectionOnRequestCompletion: 'true',
             rowCollectionOnDone: 'true'
     },
 };
var sql = new Connection(config);
var addElem = (obj, elem)=> [].push.call(obj, elem);
var result = {}, tmpCol = {}, tmpRow = {};
module.exports = {
  displayStock: function (es) {
      var dloop = setInterval(function() {
      if(result.error !== null)
            if (es) es.send(JSON.stringify(result), {event: 'rmSoH', id: (new Date()).toLocaleTimeString()});
      if(result.error === null)
            if (es) es.send('connection is closed');
      }, 1000);
  },
  fetchStock: function () {
            request = new Request("SELECT ItemCode, WhsCode, OnHand FROM OITW where OnHand > 0 and (WhsCode ='RM' or WhsCode ='FG');", function(err, rowCount, rows) {
            if (err) {
            result = {'error': err};
            console.log((new Date()).toLocaleTimeString()+' err : '+err);
             }
             if(rows)
             rows.forEach(function(row){
                 row.forEach(function(column){
                     var colName = column.metadata.colName;
                     var value = column.value;
                     addElem(tmpCol, {colName: value})
                 });
             addElem(tmpRow,{'item': tmpCol[0].colName, 'Whs': tmpCol[1].colName, 'Qty': tmpCol[2].colName});
             tmpCol = {};
           });
           result = tmpRow;
           tmpRow={}
       });
    sql.execSql(request);
  }
}

我认为您需要一个简单的变量来检查是否已经有正在运行的请求而不是Promise

var latch = false;
// It will be called only if the previous call is completed
var doFetchStock = () => sql.execSql(new Request("SQL", (err, rowCount, rows) => {
  // Your logic dealing with result
  // Initializes the latch
  latch = false;
});
module.exports = {
  fetchStock: function () {
    // Check if the previous request is completed or not
    if (!latch) {
      // Sets the latch
      latch = true;
      // Fetches stock
      doFetchStock();
    }
  }
};

事实上,我已经使用了很多这种模式,只允许一些行为出现一次。

  • https://github.com/cettia/cettia-javascript-client/blob/1.0.0-Beta1/cettia.js#L397-L413
  • https://github.com/cettia/cettia-javascript-client/blob/1.0.0-Beta1/cettia.js#L775-L797

由于javascript是单线程的,因此在客户端上这样的简单代码就足够了

function () {
       if(currentPromise != null){ // define in a closure outside
            currentPromise = [..] // call to server which return a promise
            currentPromise.then(function(){
                currentPromise = null;
            });
       }
}