Javascript Promise().then 以防止在执行第一次调用之前重新调用该函数

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

在我的 node.js 应用程序中,使用繁琐的方式从 MSSQL 读取数据,我每 1 秒调用一次以下代码:

  1. 从服务器获取数据(fetchStock函数)并将其保存在临时数组中
  2. 使用服务器发送事件(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);
  }
}

因为 javascript 是单线程的,像这样的简单代码在客户端就足够了

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

我认为您需要的是一个简单的变量来检查是否已经有 运行 请求而不是 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();
    }
  }
};

实际上我经常使用这种模式来允许某些行为只发生一次。