在回调和事件之后调用方法

Call a method after a callback and an event

本文关键字:调用 方法 之后 事件 回调      更新时间:2023-09-26

我有一个模块,它有四个函数,一个接一个地调用。我正在努力遵循揭示模块模式。其中一项功能是公共的,其余功能是私人的。它是这样的:

  1. 从另一个模块调用publicMethod
  2. publicMethod调用queryNames
  3. queryNames调用execute(parameters, callback?, errback?)
  4. addNamesList被调用为executecallback?自变量
  5. 创建了几个dijit/form/CheckBox,并触发了方法querySegments onChange
  6. CCD_ 12需要调用在CCD_ 13中创建的对象的方法

问题是在步骤6中,我无法访问在步骤1中创建的对象。

在步骤3中,我曾尝试使用dojo-hatch来定义callback?参数,但我无法使其发挥作用。我尝试将this放在它的第一个参数中,但即使这样,我也无法达到调用addNamesList所需的范围。

这里有一些代码来演示这个问题。

define([
  'dojo/dom',
  'dijit/form/CheckBox',
  'esri/layers/ArcGISDynamicMapServiceLayer',
  'esri/tasks/query',
  'esri/tasks/QueryTask',
  'dojo/_base/lang'
],
  function (
    dom,
    CheckBox,
    ArcGISDynamicMapServiceLayer,
    Query, QueryTask,
    lang
  ) {
    // ***************
    // private methods
    // ***************
    // fetch names and call addNamesList to put the list in place
    var queryNames = function (map, mapLayer) {
      // new QueryTask(url, options?)
      var queryTask = new QueryTask("url")
      var query = new Query()
      // execute(parameters, callback?, errback?)
      // this callback passes an argument called featureSet
      queryTask.execute(query, lang.hitch(map, "addNamesList", mapLayer), function(error) {console.log(error)})
    }  
    // callback function of queryNames
    var addNamesList = function (mapLayer, featureSet) {
      console.log('addOplist')
      var namesCount = featureSet.features.length
      for (var i = 0; i <namesCount; i++) {
        // work
        var cbox = new CheckBox({
          id: "cbox_" + i,
          value: featureSet.features[i].attributes["someID"],
          checked: false,
          onChange: function (evt) {
            querySegments(this.value, mapLayer)
          }
        })
        cbox.placeAt("someDiv" + i, "first")
      }
    }
    // triggered by the checkbox event
    var querySegments = function (name, mapLayer) {
        // build the query
        var queryStatement = "someID = " + name
        var layerDefinitions = [queryStatement]
        // call a method of mapLayer
        mapLayer.setLayerDefinitions(layerDefinitions)
    }
    // **************
    // public methods
    // **************
    var publicMethod = function (map) {
      var mapLayer = new ArcGISDynamicMapServiceLayer('restURL')
      map.addLayer(mapServiceLayer)
      queryNames(map, mapLayer)
      return mapLayer
    }
    return {
      publicMethod: publicMethod
    }
  }
)

您可以看到我在代码审查中提出的另一个(更广泛的)问题的更详细的解释和工作示例。

我是JavaScript的新手,我想我在范围界定、闭包和回调方面仍然有很多问题。

我将非常感谢任何意见,包括如何改进这个问题。

编辑

使用当前的实现(使用dojo挂接),不会引发任何错误。没有调用方法addNamesList(也没有调用errback,我也不明白为什么)。我认为这是因为addNamesList不在map的(挂接第一个参数)命名空间中。我试着用this代替,但没有什么区别。

在我决定使用挂接之前,代码看起来是这样的:

var queryNames = function (map, mapLayer) {
  ...
  queryTask.execute(query, addNamesList)
}
var addNamesList = function (featureSet) {
  ...
    ...
      ...
        querySegments(this.value, mapLayer)
}

但随后我无法在复选框事件触发的方法内访问CCD_ 22。它会抛出Uncaught ReferenceError: mapLayer is not defined。这就是我尝试使用挂接的原因。

Javascript是异步的,所以大部分数据来自db、http请求或通过回调返回的任何东西。以下是代码中发生的情况:

  • 公共方法调用queryNames
  • queryNames异步调用mapaddNamesList,不返回任何结果
  • 公共方法收回了控制权,同时addNamesList也发生了一些事情
  • mapLayer原封不动地返回,而一些东西仍在后台进行

因此,为了避免这种情况,您应该通过回调从公共方法返回数据,因此将callback作为第二个参数传递给公共方法,然后传递给querySegments。然后,在query的成功回调中,当您最终准备好结果时,您执行:

callback(mapLayer);

所以,你应该做的一切就是根据需要将这个callback传递到你准备好mapLayer的地方(所以你已经完成了你想要的一切),然后做一个callback(mapLayer);

这个和这个可能会解释得更好。

致以最良好的问候,Alexander