如何使用 $.Deferred 和额外的回调函数构建函数来处理数组

How to build function to process array with $.Deferred and extra callback function

我需要通过 HERE 地图地理编码器处理数据列表,以便将 locationId 转换为坐标。 geocoder class 具有 geocode 函数,该函数采用 3 个参数 1 个参数 2.successCallFunction 3.failCallFunction。

  self.geocodeByLocationIdByArray = function (locationIds, callback)
            {
                var deferred = $.Deferred();
                var result = []; 

                var convert = function () {
                    for (var i = 0; i < locationIds.length - 1; i++)
                    {
                        geocodingParameters = {
                            locationId: locationIds[i].locationId;
                        };
                        self.geocoder.geocoder(geocodingParameters, onGeocodeSuccess, function () { });
                    }

                };

                convert();
                return deferred.promise();
            };

 onGeocodeSuccess = function (result) {

                var locations = result.Response.View[0].Result,
                    i;
                var result = [];
                // Add a marker for each location found
                for (i = 0; i < locations.length; i++) {
                    result.push(new geoCoordinate(locations[i].Location.DisplayPosition.Latitude, locations[i].Location.DisplayPosition.Longitude));
                }

                return result;
            };

如何修复 geocodeByLocationIdByArray 函数以等待所有数据都位于前面并且 return 结果数组?我有点停了:(我的问题是地理编码器是异步的。

您可以承诺 geocoder 方法,这样它就不会得到回调作为参数,但 return 是一个承诺。然后您可以创建一个承诺数组,每个承诺都由这个新函数创建。最后,您可以使用 $.when 等待所有这些承诺解决,将结果和 return 连接起来作为整体 geocodeByLocationIdByArray 方法的承诺值。

这是未经测试的代码,但您会明白的:

self.geocodeByLocationIdByArray = function (locationIds) {
    // Promisify geocoder:
    function geocoderPromise(geocodingParameters) {
        var deferred = $.Deferred();
        self.geocoder.geocoder(geocodingParameters, function () {
            deferred.resolve(result);
        }, function (err) {
            deferred.reject(err);
        });
        return deferred.promise();
    }

    // Create an array of promises
    var promises = locationIds.map(function (locationId) {
        var geocodingParameters = {
            locationId: locationIds[i].locationId;
        };
        return geocoderPromise(geocodingParameters)
            .then(onGeocodeSuccess)
            .catch(function (err) { // or `fail` in jQuery < 3.0
                console.log('geocoder error occurred', err);
            });
    });
    // Wait for all promises to be resolved, and then concatenate the results
    // as the final promised value.
    return $.when.apply($, promises).then(function () {
        return [].concat.apply([], arguments); 
    });
};

请注意,此代码不再有回调参数,但您也需要将 geocodeByLocationIdByArray() 的 return 值视为一个承诺。所以你会写:

self.geocodeByLocationIdByArray([....ids....]).then(function (result) {
    console.log(results);
});