如何在javascript中添加回调函数,该函数连续两次使用不同的参数调用?

时间:2017-12-26 16:26:36

标签: javascript callback webix

我有一个用不同参数调用两次的函数:

function setArray(chartType, charData, nodeName, meaQuantityId, unitName) {
  var legendText = nodeName + '(' + unitName + ')';
  var lineData = null;
  var scatterData = null;
  if (chartType != null) {
    switch (chartType) {
      case 'line':
        {
          if (compareGraphData.length > 0) {
            for (var i = 0; i < compareGraphData.length; i++) {
              if (legendText == compareGraphData[i].legendText) {
                legendText = changeLegendText(legendText, i);
              }
            }
          }
          lineData = {
            type: chartType, //try changing to column, area
            showInLegend: true,
            legendText: legendText,
            toolTipContent: "{label}LS : {y} ",
            dataPoints: charData
          };
          compareGraphData.push(lineData);
          break;
        }
      case 'scatter':
        {
          if (compareScatterGraphData.length > 0) {
            for (var i = 0; i < compareScatterGraphData.length; i++) {
              if (legendText == compareScatterGraphData[i].legendText) {
                //legendText = changeLegendText(legendText, i);
              }
            }
          }
          scatterData = {
            type: chartType, //try changing to column, area
            showInLegend: true,
            legendText: legendText,
            toolTipContent: "{label}LS : {y} ",
            dataPoints: charData
          };
          compareScatterGraphData.push(scatterData);
          break;
        }
    }
  } else {
    var arr = [];
    for (var i = 0; i < charData.length; i++) {
      arr.push({
        'quantityName': charData[0].nodeName,
        'data': charData[i].value,
        'count': charData[0].count,
        'unitName': charData[0].xUnitName,
        'meaQuantityId': meaQuantIdForDataTable
      });
    }
    dataView.push(arr);
  }
}

function changeLegendText(legendText, i) {
  var value = webix.ui({
    view: "window",
    modal: true,
    id: 'id-win-change-channel-Name',
    fullscreen: true,
    position: function(state) {
      state.width = 220;
      state.top = 200;
      state.left = (window.innerWidth - state.width) / 2;
      state.height = 150;
    },

    head: "Change Alias!",
    body: {
      padding: 10,
      rows: [{
        view: 'text',
        id: "id-text-change-channel-Name",
        value: legendText + '_' + i
      }, {
        view: 'button',
        value: "OK",
        click: function() {
          channelAliasValue = $$('id-text-change-channel-Name').getValue();

          $$('id-win-change-channel-Name').hide();
        }
      }]
    }
  }).show();
}

////I call the function like this:

DBService.getGraphData('getGraphData')
    .then(function(response){
    var charData=response.result;
    setArray('line', charData, nodeName, meaQuantityId, unitName);
    setArray('line', charData, nodeName, meaQuantityId, unitName);
});
我将legendTextcompareGraphData数组中的SELECT TIMESTAMPDIFF(SECOND, FROM_UNIXTIME(0), '1956-12-24 01:06:49');进行了比较。如果是,那么弹出窗口会出现一个文本框和一个按钮。

我想在弹出窗口时停止执行,并在用户点击按钮后继续执行。

但是以上代码不会等待用户事件并继续下一个语句。

你能告诉我实现这个目标的最佳途径吗?

3 个答案:

答案 0 :(得分:0)

你可以将一个函数传递给你的函数:

dateStyle

timeStyle

或使用async

答案 1 :(得分:0)

在异步执行的情况下(缺少setArray函数体并不清楚),可以使用promises解决此问题。参考此处:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

let setArray = function setArray('line', data) {
  return new Promise((resolve, reject) => {
    // logic for function setArray here
  });
};

let call1 = setArray('line', data).then(function(result) {
  // do stuff with result
});

let call2 = setArray('scatter', data).then(function(result) {
   // do stuff with result
});

但是,如果setArray的函数体没有异步部分,则可以毫无问题地执行常规函数调用。如果它不起作用,则代码可能存在另一个问题。

答案 2 :(得分:0)

我认为你想要的只是使用最后的改变。

例如,用户有一个所有动物的列表,可以选择只显示慢动物或快动物,但过滤器是异步的。

用户点击只显示慢动物,过滤器返回数据需要1秒钟。在这一秒内,用户选择显示所有动物,因此用户界面设置为显示所有动物。显示全部需要100毫秒,返回并更新列表以显示所有内容。然后慢动物列表进来,列表只显示慢动物。

现在,用户界面和显示的列表不同步。 here描述了此问题。

我实现的这个问题的solution是将一个承诺传递给一个函数,该函数只会解析承诺,如果它是最后创建的承诺(最近的用户操作)。 / p>

如何将使用回调的函数转换为返回promise的函数here(在:将回调转换为promise。)

<强> [UPDATE]

如昨天所述;我认为用户会更改某些内容然后更改其他内容,因此2个承诺会获取在用户创建它们的同时无法解析的数据和/或两者都在解析,因此您的应用程序正在执行不再需要的操作。

我昨天给出的答案可以使用lib中的onlyLastPromise以下列方式应用于您的代码:

const onlyLastRequestedPromise = ((promiseIds) => {
  const whenResolve = (promise, id, promiseID, resolveValue) => {
    if(promise!==undefined){//called by user adding a promise
      promiseIds[id]={};
    } else {//called because promise is resolved
      return (promiseID === promiseIds[id])
        ? Promise.resolve(resolveValue)
        : Promise.reject("A newer request was made.")
    }
    return (function (currentPromiseID) {
      return promise
        .then(function (result) {
          return whenResolve(undefined,id, currentPromiseID, result);
        });
    }(promiseIds[id]));
  };
  return (id = "general") => promise =>
    whenResolve(promise, id);
})({});
//this is for your fetching your data, add it to your service
const lastForChart=onlyLastRequestedPromise("CHART_DATA");

//wrap your getGraphData in a "only last"
lastForChart(DBService.getGraphData('getGraphData'))
.then(
  function(response){
    var charData=response.result;
    setArray('line', charData, nodeName, meaQuantityId, unitName);
    setArray('line', charData, nodeName, meaQuantityId, unitName);
})
.catch(
  err=>
    (err==="A newer request was made.")
      ? "replaced by newer request"
      : Promise.reject(err)
);