【问题标题】:Wait for the end of an asynchronous Javascript function to retrieve a result (Deferred ?)等待异步 Javascript 函数结束以检索结果(延迟?)
【发布时间】:2013-10-01 20:52:35
【问题描述】:

好的,伙计们,我知道这个话题已经讨论过很多次了,但是我找不到解决我问题的答案。

所以我想做一个简单的思考: 我正在创建一个字符串,例如:distance is : " + CalculateDistance(position); 想要的结果类似于distance is 5kms (8min)

CalculateDistance(position) 是一个调用名为 DistanceMatrix 的谷歌地图 API 来计算两点之间距离的函数。 API 记录在 here 中,并且给定的示例完美运行。我是这样改编的:

function CalculateDistance(position)
{
    var service = new google.maps.DistanceMatrixService();
    var destination = new google.maps.LatLng(/* some lat/lng */);

    service.getDistanceMatrix(
    {
        origins: [position],
        destinations: [destination],
        travelMode: google.maps.TravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.METRIC,
        avoidHighways: false,
        avoidTolls: false
    }, callback);
}

function callback(response, status) {
    if (status == google.maps.DistanceMatrixStatus.OK)
    {
        var origins = response.originAddresses;
        var destinations = response.destinationAddresses;

        var results = response.rows[0].elements;
        distanceMatrixResult = results[0].distance.text + " ( " + results[0].duration.text + " min)";
    }

哦,顺便说一句,distanceMatrixResult 是一个全局变量。实际上,我只需要获取 results[0].distance.text 的内容(当我在callback() 的控制台中打印它时,值就可以了),然后将值与“距离是”连接起来。如果有人有更聪明的解决方案,欢迎!

API 调用是异步,在我的例子中,distanceMatrixResult 在结果字符串中始终为空。但是当我在控制台中记录它的值时,distanceMatrixResult 值变成了 AFTER 字符串创建后的好值。

我只想写:

• 调用CalculateDistance(异步调用回调)
• 当callback 结束时,将字符串与distanceMatrixResult 值连接起来。

我尝试了一些Deferred,例如$.done()$.when().then(),但我无法成功...

有人可以帮我吗?
谢谢!

【问题讨论】:

    标签: javascript jquery jquery-deferred deferred


    【解决方案1】:

    distanceMatrixResult 是一个全局变量

    它不应该,它应该是你的 Promise (Deferred) 所代表的值。这是基本设置:

    function calculateDistance(position) {
        var service = new google.maps.DistanceMatrixService();
        var destination = new google.maps.LatLng(/* some lat/lng */);
        var dfd = $.Deferred();
        service.getDistanceMatrix({
            origins: [position],
            destinations: [destination],
            travelMode: google.maps.TravelMode.DRIVING,
            unitSystem: google.maps.UnitSystem.METRIC,
            avoidHighways: false,
            avoidTolls: false
        }, function(response, status) {
            if (status == google.maps.DistanceMatrixStatus.OK)
                dfd.resolve(response);
            else
                dfd.reject(status);
        });
        return dfd.promise();
    }
    

    现在,你想做的事

    calculateDistance(…).then(function(response) {
        var origins = response.originAddresses;
        var destinations = response.destinationAddresses;
        var results = response.rows[0].elements;
        return results[0].distance.text + " ( " + results[0].duration.text + " min)";
    }).done(function(distanceMatrixResult) {
        var myString = "distance is: "+distanceMatrixResult;
        // do something with your string now
    });
    

    【讨论】:

    • 我非常感谢@Bergi,mystring 中的值很好,非常感谢!为了一切正常,还有一些事情要做,但是您的回答将使我进步并更好地理解 Deferred。
    • 很抱歉直接问你另一个问题,我想调用calculateDistance() 三次并将DistanceMatrix API 的结果连接到myString。我尝试了 som for 循环,但我总是在myString 中得到第一个结果...你知道如何实现这个@Bergi 吗?
    • 我不确定你到底做了什么,但你可能需要look into closures for (async) callbacks that are called after the loop$.when 等待多个承诺解决。如果这些链接没有帮助,请在您的代码中发布另一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-11
    • 2020-04-08
    • 1970-01-01
    相关资源
    最近更新 更多