调用jqXHR.done()

时间:2017-10-25 05:12:59

标签: javascript jquery asynchronous async.js

我有一个异步函数,它调用一个返回jQuery XMLHTTPRequest(jqXHR)对象的函数,该函数在完成后会执行一些工作并调用回调。不幸的是,当我在async.waterfall()中的其他函数之前和之后使用所述函数时,函数.done()似乎在其他所有内容已经完成后被调用(包括此后的函数,以及async.waterfall())结束时的成功/失败回调。

函数定义如下所示:

function snapPotholeCoordsToRoad(potholeCollection, callback)
{
    var DEBUG = true;
    // guarantee that callback is function
    if ((callback) && (typeof(callback) !== 'function')) throw new TypeError('callback is something, but not a function. Thrown from snapPotholeCoordsToRoad().');
    // for each element of potholeCoordinates
    for (var key in potholeCoordinates)
    {
        (function itr(k, m) { 
            if (m === potholeCoordinates[key].length) return;
            if (DEBUG) console.log('called before the jqXHR.done()');
            // if element (PotholeData) not snapped to road
            if (!potholeCoordinates[k][m].isSnappedToRoad())
            {
                // get road coordinates for element
                getRoadCoordinates(potholeCoordinates[k][m])
                // replace element's coordinates with those road coordinates
                .done(function(newCoords) { 
                    potholeCoordinates[k][m].setCoordinates(newCoords.snappedPoints[0].location);
                    potholeCoordinates[k][m].isSnappedToRoad(true);
                    if (DEBUG) console.log('called after jqXHR.done()');
                    itr(k, m+1);
                })
            }
            else itr(k, m+1);
        })(key, 0);
    }
    if (callback)
    {
        callback(null);
    }
}

其中potholeCoordinatesObject Array的{​​{1}}个PotholeData

getRoadCoordinates()看起来像这样:

/* snaps the coordinates to the nearest road
 * Parameters:
 *  • coords : coordinates object`
 * Returns: 
 *  • coordinates, snapped to road 
 * NOTE: the points you're looking for are accessible via the snappedPoints member of the returned object (in done() or success()) 
 */
function getRoadCoordinates(coords)
{
    return $.ajax({
        type: 'get',
        url : 'https://roads.googleapis.com/v1/snapToRoads',
        data: { 
            key : API_KEY,
            interpolate : true,
            path : coords.lat + ', ' + coords.lng
        }
     });
}

... async.waterfall()就像这样:

async.waterfall([//fetchServerPotholeData,  // for some reason, this function is not receiving data
            function(callback) { 
                fetchServerPotholeData(data, callback);
            },
            fetchRoadCoords,
            snapPotholeCoordsToRoad,
            addPotholeMarkers
            ], function(err, result) { 
                if (!err) { 
                    console.log('result == ' + result);
                    console.log('Everything successfully done. Enjoy your map!'); 

                }
                else 
                {
                    console.error(err);
                }
            }
        )

/ *它位于一个传递它的函数data内。 * /

在运行时,我得到的控制台输出类似于:

called before the jqXHR.done()
result == undefined
Everything successfully done. Enjoy your map!
called after jqXHR.done()

我需要更改什么才能使.done()在这些循环中的滴答声中执行,然后是其余的代码?

1 个答案:

答案 0 :(得分:0)

我刚刚在发布此消息后的几分钟内解决了这个问题,我刚刚解决了错误!

我做了什么

在第一个for循环之前,我保存了potholeCoordinates键的副本

var keys = Object.keys(potholeCoordinates);

并在.done()回调内,最后,就在

之前
itr(k, m+1);

我检查我是否在最后一个数组中的最后一个对象上,使用:

if ((k === keys[keys.length - 1]) && (callback)) return callback(null);

编辑:我忘记了我已经取消了

if (callback) 
{
    callback(null);
}

在for循环之外

/ *我现在可能应该重构这段代码,以便实际使用它们的参数,就像它们应该是.... * /