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

时间:2016-04-18 07:50:47

标签: javascript ecmascript-6 server-sent-events es6-promise

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

  1. 从服务器(fetchStock函数)获取数据并将其保存在临时数组
  2. 使用服务器发送事件(SSE)API将保存在临时阵列中的数据发送到客户端。
  3. 看起来1秒还不足以在完成前一个调用之前调用fetchStock函数,因此我不时会遇到执行错误。 我把它增加到5秒,但每隔一段时间仍然会得到同样的问题。

    如何使用Promise().then确保在完全执行previouse调用之前不会重新调用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);
      }
    }
    

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

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