繁体   English   中英

递延,承诺和Ajax的顺序不正确

[英]Deferred, Promises, and Ajax not going in correct order

我试图建立一个Ajax调用循环,并在所有Ajax调用解决后运行一个函数。 我通读了许多关于此问题的SO问题,并认为我可以将其应用于代码中,但是它无法正常工作,我一生都无法找出原因。

这是JS代码。 map function运行时间是FYI的10倍。

function addData(data) {
    var deferreds = [];
    $.map(data, function(job) {
        deferreds.push(addLocation(job));
    });

    console.log(deferreds);
    $.when.apply($, deferreds).then(mapData(data));
}

function addLocation(job) {
    var dfd = $.Deferred(),
        url = url;

    console.log('in the addLocation function, outside the ajax call');
    $.ajax({
        url: url,
        dataType: 'jsonp',
        jsonp: 'json_callback'
    }).done(function(location) {
        job.lnglat = [parseFloat(location[0].lon), parseFloat(location[0].lat)];
        console.log('resolved location');
        dfd.resolve();
    });

    return dfd.promise();
}

function mapData(data) {
    console.log('in the mapData function');
    console.log(data);
    var point = svg.selectAll('points')
        .data(data);

    point.exit().remove();
    point.enter().append('circle')
        .attr('r', 2.5);

    point
        .attr('cx', function(d) {
            console.log(d);   //shows d and has the lnglat but I think that is due to the developer tools reading the final result, not the result at the time
            console.log(d.lnglat);   // this gives undefined
            console.log(d.lnglat[0]); // this gives an error as it hasn't been defined
            console.log(projection(d.lnglat[0]));
            return projection(d.lnglat[0])[0];
        })
        .attr('cy', function(d) {
            return projection(d.lnglat[1])[1];
        });
}

Chrome开发人员工具报告以下顺序:

in the addLocation function, outside the ajax call  //x10
[Object, object...] //this is the object list of deferred objects, there are 10 of them
in the mapData function
[Object, object..] //this is the object list of data from the mapData function
Object > ... //this is the d object in the mapData function > point anonymous function
undefined // this is the result of d.lnglat
Uncaught typeError ... // this is the result of d.lnglat[0] which doesn't exist yet
resolvedLocation //x10 this should be a lot higher right?

所以我想让in the mapData function resolvedLocation console.log in the mapData function运行之前运行,我想我已经用这种方式进行了设置,但显然不起作用。 我想念什么?

正如adeneo在他的评论中所说,这里的问题是在

$ .when.apply($,deferreds).then(mapData(data))

为了解决这个问题,您需要使用bind来使您的大多数解决方案保持完整(并且不要对其进行太多更改)。 这应该工作:

$ .when.apply($,deferreds).then(mapData.bind(this,data))

绑定不会延迟该函数的调用。 它将数据参数绑定到函数的调用上,因此,当“ then”函数调用mapData时,它将以“ data”作为参数来进行调用,并且仅在所有promise都解决后才会发生。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM