首页 > 解决方案 > Javascript函数异步执行,我不希望它

问题描述

我正在为一个学校项目制作一个导航网络应用程序。它使用一个名为“EasyStar”的程序进行寻路。因为我需要经常计算一些点之间的距离,所以我决定为它创建一个函数:

function Distance(A, B, C, D, G) {
easystar.setGrid(G);
easystar.findPath(A, B, C, D, function( path ) {
Dist = 1;
for (F = 0; F < Dist; F++){
if (typeof path[F] !== "undefined"){Dist++;}
else{}
}});
easystar.calculate();
}

我面临的问题是,当我调用该函数时,它在执行下一段代码后完成:如果我在函数本身的末尾和函数应该执行后立即在控制台中记录 Dist,结果是:

undefined
[The actual distance]

如果我做这样的事情

setTimeout(function(){console.log(Dist)},0.001)

或者 0.001 毫秒的延迟,它确实正确显示,我可以开始使用 Dist 的值。该解决方案的问题是我无法在整个文档中保持这种状态,因为它会变得非常混乱,我什至不确定它是否可以作为永久解决方案。

标签: javascriptasynchronoussynchronization

解决方案


由于 EasyPath 是异步运行的,因此您无法确定传递给的函数何时findPath()会被执行。出于这个原因,任何需要最终值的逻辑Dist都必须放在这个函数中。由于这会很快变得丑陋,因此您可以将成功回调传递给在计算Distance()后调用的成功回调,就像这样。Dist

function myFunc() {
    var grid = [
        [0, 0, 1, 0, 0],
        [0, 0, 1, 0, 0],
        [0, 0, 1, 0, 0],
        [0, 0, 1, 0, 0],
        [0, 0, 0, 0, 0]
    ];
    Distance(0, 0, 4, 0, grid, handleDist);
};

var handleDist = function(dist) {
    // Do something with dist.
};

function Distance(A, B, C, D, G, callback) {
    easystar.setGrid(G);
    easystar.findPath(A, B, C, D, function(path) {
        Dist = 1;
        for (F = 0; F < Dist; F++) {
            if (typeof path[F] !== null) { Dist++; }
            else { }
        }
        callback(Dist);
    });
    easystar.calculate();
}

myFunc()只是如何Distance()调用的示例。如您所见handleDist(),您将编写一个单独的函数来处理Dist. 您将其传递给Distance()并在 的回调中调用它findPath()

Promise将有助于进一步清理此代码,但由于我不熟悉 EasyPath,我不确定它是否支持它们。


推荐阅读