javascript - 带 2 个回调的异步 javascript - 如何实现?

标签 javascript asynchronous callback

我需要代码像这样流动:从 calcRoute (谷歌地图距离)获取值 -> 添加到数组(?)/添加到输出字符串,直到它遍历完所有值。然后追加到 ListView 。

var myArray = [];
$.get( "http://www.url.com/info.php", function( data ) {

        var output = "";
        var imgsrc = "";

         obj = jQuery.parseJSON(data);


        for (i = 0; i < obj.length; i++) 
            { 

                store=obj[i].store;

            for (j = 0; j < obj[i].products.length; j++) 
                { 
                    productname= obj[i].products[j].productname;
                    price=obj[i].products[j].price;

                    calcRoute(function(returnValue) {

                        myArray.push(returnValue);
                        console.log("Inside callback : " + flowcounter++);
                        console.log("Inside callback (Array): " + myArray);
                    }); 

                    console.log("Array has now (J-loop) : " + myArray);
                    console.log("Flowcounter has now (J-loop) : " + flowcounter++);
                    output+='<li> <img style="margin-left: 8px" width="80" height="80" alt="sample" src="img/logo.png" align="left"/> <h3>'+ productname+' '+price+'</h3><p>Ca:'+ myArray[i] +' km.</p> </li>';                 
                }

            }


        console.log("Append to list (Counter) : " + flowcounter++);
        console.log("Appen to list(Array): " + myArray);
        $("#prodlist").append(output).listview().listview('refresh');

            });

但现在它是这样的:J-loop -> 附加到 ListView -> calcRoute。 所以在执行下一步之前它没有值。这里的问题显然是我需要获取一个值,将其放入输出中,当它们全部完成后,放入 prodlist-append 中。 这是 calcRoute 代码:

        function calcRoute(callback) {

        var start = new google.maps.LatLng(55.613520,12.534539);
        var end = new google.maps.LatLng(55.713520,12.534539);

    var request = {
          origin: start,
          destination: end,
          travelMode: google.maps.TravelMode["DRIVING"]
      };
      directionsService.route(request, function(response, status) {
          if (status == google.maps.DirectionsStatus.OK) {
              directionsDisplay.setDirections(response);
          }
          var totalDistance = 0;
          var legs = response.routes[0].legs;
          for(var i=0; i<legs.length; ++i) {
             totalDistance += legs[i].distance.value;
          }
          totalDistance = totalDistance / 1000;
         totalDistance = totalDistance.toFixed(1);
         myArray.push(totalDistance);
         callback(totalDistance);
     });
    };

还添加了 logcat:Logcat of flow

感谢任何帮助。

最佳答案

看看Javascript Promises .

它们允许您链接异步操作,例如:

doThing1().then(doThing2()).then(doThing3());

或者可能更适合您的目的,Promise.all将等到所有操作完成后再执行下一步操作:

Promise.all([
    doThing1(),
    doThing2(),
    doThing3()
]).then(addToList(results));

Here's a jsfiddle这概述了您可能在这里做的事情。我不知道你到底想做什么,但希望这足以让你行动起来。

Javascript:

var storeData = [
    {
        name: 'Store 1',
        location: {
            lat: 55.613520,
            lng: 12.534539
        },
        products: [
            {
                productname: "Product 1",
                price: 1.10
            },
            {
                productname: "Product 2",
                price: 2.20
            }
        ]
    },
    {
        name: 'Store 2',
        location: {
            lat: 55.613520,
            lng: 12.634539
        },
        products: [
            {
                productname: "Product 1.1",
                price: 1.11
            }
        ]
    }
];

// wraps a jquery ajax request for store data in a Promise
function getStores() {
    return new Promise(function(fulfill, reject) {

        // this is a jsfiddle ajax request
        // that just returns the json you send it (storeData).
        $.post( '/echo/json/', {
            json: JSON.stringify(storeData),
            delay: 1
        })
        .done(function(result) {
            return fulfill(result);    
        })
        .fail(function(reason) {
            return reject(reason);
        });
    });
}

function calcRoute(store) {
    return new Promise(function(fulfill, reject) {
        // call google here. faking it for the fiddle.
        return fulfill({
            result: 'Fake route result for store ' + store.name
        });
    });
}

function getRoutes(stores) {
    var promises = [];
    for (var i = 0; i < stores.length; i++) {
        promises.push(calcRoute(stores[i]));
    }
    return Promise.all(promises);
}

function updateDisplay(routes) {
    var list = document.getElementById('list');
    for (var i = 0; i < routes.length; i++ ) {
        console.log(routes[i].result);
        $(list).append('<li>' + routes[i].result + '</li>');
    }
}

function go() {
    return getStores()
    .then(getRoutes)
    .then(updateDisplay)
    .catch(function(reason) {
        console.error('Error %O', reason);
    });
}

$.ready(go());

关于javascript - 带 2 个回调的异步 javascript - 如何实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30335302/

相关文章:

javascript - 具有特定数字的输入类型范围

javascript - Drupal - 如果关闭 JS,是否有特殊的 css 文件?

javascript - 等待许多异步函数执行

c# - 如何使用 linq 进行异步

C#/.NET - 使用异步/等待函数调用时 CPU 使用率非常高

javascript - 通过回调在 JavaScript 中管理队列

javascript - 通过基础模型进行 Strongloop API 查询

javascript - 此 javascript 是否有任何原因无法更改我的 IFrame 上的 "src"属性?

callback - Julia 中的函数句柄

javascript - jQuery回调函数累积