如何在加载所有数据时运行函数

How to run a function when all the data loaded?

本文关键字:数据 运行 函数 加载      更新时间:2023-09-26

我在ArcGIS JS API中异步处理数千个点。在 main 函数中,我调用处理单个特征的函数,但我需要在处理完所有特征时完成处理。应该有一个事件,虽然我没有找到任何事件,恐怕它甚至不存在 - 很难说最后处理的项目是最后一个.ajaxStop()应该这样做,但我不使用jQuery,只使用Dojo。我在 Dojo 中找到的最接近的是 Fetch 及其 OnComplete,但据我所知,它是关于从 AJAX 获取数据,而不是从其他 JS 函数获取数据。

我现在唯一的解决方法是测量要处理的特征数量,然后在输出点数组达到所需长度时触发,但我首先需要计算所需的数量。但是如何在加载时做到这一点?将数据跟踪到从服务器读取它们的位置意味着修改我什至不应该知道的功能,这是不可能的。

编辑 - 我的一些代码:

addData: function (data) {
    dojo.addOnLoad(
        this.allData = data,
        this._myFunction()
    );
},

一些评论:

  • data是一个图形数组
  • 当我在调试器中查看data时,它的计数是 2000,然后是 3000,然后是 4000...
  • 如果没有dojo.addOnLoad,计数开始接近零,现在大约是 2000 年,但仍然是实际数字的一小部分
  • _myFunction() this._allData处理所有 2000...3000...4000... 图形,并返回错误的结果,因为它需要它们才能正常工作
  • 我需要延迟执行_myFunction(),直到所有数据加载,也许是通过其他事件而不是dojo.addOnLoad.

我已经有的解决方法:

a) setTimeout()

这显然是一个错误的选择 - 如果data包含太多项目,等待的任何神奇毫秒数都无法拯救我,甚至会延迟数组中单个点的情况。

b) 基于长度的延迟

我可以用这样的东西替换事件:

if(data.length == allDataCount) {
    this._myFunction();
}
setTimeout(this._thisFunction, someDelay);

相同的其他一些实现,通过循环或计数器在异步调用的函数中递增。问题是如何确保allDataCount变量是确定的,而不仅仅是迄今为止引导的特征数量。

EDIT2:指出@tik27的延迟和承诺肯定对我有帮助,但我发现将同步代码转换为延迟代码的最好例子就是这个简单的例子。我可能误解了一些东西,因为它并不比原始的同步代码更好,this.allData仍然不能保证保存所有数据。加载函数现在如下所示:

addData: function (data) {
        var deferred = new Deferred();
        this._addDataSync(data, function (error, result) {
            if (error) {
                deferred.reject(error);
            }
            else {
                deferred.resolve(result);
            }
        });
        deferred.promise.then(this._myFunction());
    },
    _addDataSync: function (data, callback) {
        callback(this.allData = data);
    },

我知道大多数延迟假设从某个服务器请求数据的用例。但这是我第一次可以在不破坏我不应该更改的功能的情况下处理数据,因此将数据跟踪回请求不是一种选择。

插件加载是等待dom。如果您正在等待一个函数完成以运行另一个函数,则使用延迟/承诺。

需要有关您的程序的更多信息,以便为您提供更具体的答案。

我解决了我的问题,延迟了对图层构造函数的调用,直到地图完全加载并且"onUpdateEnd"事件触发。这可能是正确完成的方式,所以我将其作为答案发布,而不是作为我问题的编辑。另一方面,我无法控制班上的其他调用,我宁愿有另一道防线来防止不完整的输入,或者至少有一种方法来判断我是否应该抱怨不完整的数据,所以我保持答案不被接受,问题开放以获得更多答案。

当我重新加载页面时,这不起作用,但后来我想出了如何将事件侦听器正确地链接在一起,所以我现在可以"onUpdateEnd"与范围更改或任何其他事件相结合。这完全足以满足我的需求。