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

具有2个回调的异步javascript-如何实现?,javascript,asynchronous,callback,Javascript,Asynchronous,Callback,我需要这样的代码:从calcRoute(google maps distance)获取值)->添加到数组(?)/添加到输出字符串,直到它遍历所有值。然后附加到listview var myArray = []; $.get( "http://www.url.com/info.php", function( data ) { var output = ""; var imgsrc = ""; obj = jQuery.parseJSON(dat

我需要这样的代码:从calcRoute(google maps distance)获取值)->添加到数组(?)/添加到输出字符串,直到它遍历所有值。然后附加到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');

            });
var myArray=[];
$.get(”http://www.url.com/info.php,函数(数据){
var输出=”;
var imgsrc=“”;
obj=jQuery.parseJSON(数据);
对于(i=0;i';
}
}
log(“附加到列表(计数器):”+flowcounter++);
log(“Appen to list(Array):”+myArray);
$(“#prodlist”).append(output.listview().listview('refresh');
});
但现在是这样的:J-loop->append to listview->calcRoute。 所以在执行下一步之前,它没有这些值。这里的问题很明显,我需要得到一个值,将其放入输出,当它们都完成后,放入prodlistappend。 以下是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);
     });
    };
函数calcRoute(回调){
var start=new google.maps.LatLng(55.613520,12.534539);
var end=new google.maps.LatLng(55.713520,12.534539);
var请求={
来源:start,
目的地:完,
travelMode:google.maps.travelMode[“驾驶”]
};
路由(请求、功能(响应、状态){
if(status==google.maps.directionstatus.OK){
方向显示。设置方向(响应);
}
var totalDistance=0;
var legs=response.routes[0]。legs;
对于(var i=0;i来看

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

doThing1()。然后(doThing2())。然后(doThing3());

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

Promise.all([
    doThing1(),
    doThing2(),
    doThing3()
]).then(addToList(results));
这概括了你在这里可能会做的事情。我不知道你到底想做什么,但希望这足以让你行动起来

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());
var-storeData=[
{
名称:“商店1”,
地点:{
拉脱维亚:55.613520,
液化天然气:12.534539
},
产品:[
{
产品名称:“产品1”,
价格:1.10
},
{
产品名称:“产品2”,
价格:2.20
}
]
},
{
名称:'商店2',
地点:{
拉脱维亚:55.613520,
液化天然气:12.634539
},
产品:[
{
产品名称:“产品1.1”,
价格:1.11
}
]
}
];
//将用于存储数据的jquery ajax请求包装到Promise中
函数getStores(){
返回新承诺(功能(履行、拒绝){
//这是一个JSFIDLE ajax请求
//它只返回您发送给它的json(storeData)。
$.post('/echo/json/'{
json:json.stringify(storeData),
延误:1
})
.完成(功能(结果){
返回(结果);
})
.失败(功能(原因){
退货拒绝(原因);
});
});
}
功能计算器(存储){
返回新承诺(功能(履行、拒绝){
//在这里打电话给谷歌,假装成小提琴。
报答({
结果:'store'+store.name的假路由结果
});
});
}
功能getRoutes(商店){
var承诺=[];
对于(变量i=0;i”+路由[i]。结果+”);
}
}
函数go(){
返回getStores()
.然后(getRoutes)
.then(更新显示)
.catch(函数(原因){
控制台错误('error%O',原因);
});
}
$.ready(go());

您可以使用嵌套回调,或者使用一些框架,您可以使用承诺链接。然后或。成功。下面是一篇关于平坦嵌套回调以避免“回调地狱”的有趣文章。

我认为您应该查看延迟调用。检查此链接,有一个很好的示例请记住此结构要求每个
doThingx()
函数返回一个承诺,该承诺在异步操作完成后得到解决。您能否指导我如何使用我的代码执行此操作?对我来说似乎根本不起作用。@Rad更新了我的答案,将示例代码/jsfiddle包含在内。同时请记住,在某些浏览器中,您可能需要一个polyfill来表示承诺,最明显的是IE<12。