JavaScript Promise未执行.then()

3

我在JavaScript中遇到了Promise的一些问题。我的目标是获取地址列表,然后对于每个地址,我需要调用geocode API来获取经纬度,然后将标记与热力图一起绘制。以下是我的代码:

let promiseKey = Promise.all(
          result.map()
        );

        var addedMarkers = promiseKey.then(
        markers => Promise.all(
          markers.map()
        )
        )
        .then(drawForecastHeatmap);

我调用地理编码 API 的部分:
function getBranchLatLng(address, branchName, total, queKey){
return new Promise(function(resolve){
    var key = jQuery.rand(geoCodKeys);
    var url = 'https://maps.googleapis.com/maps/api/geocode/json?key='+key+'&address='+address+'&sensor=false';

    $.ajaxq (qyName, {
        url: url,
        dataType: 'json'
    }).done(function( data ) {
        var address = getParameterByName('address', this.url);
        var index = errorArray.indexOf(address);
        try{
            var p = data.results[0].geometry.location;
            var latlng = new google.maps.LatLng(p.lat, p.lng);

            var markerItem =
                {
                    'lat': p.lat,
                    'lng': p.lng,
                    'address': address,
                    'branchName': branchName,
                    'total': total,
                };
            console.log(markerItem);
            resolve(markerItem);

            if (index > -1) {
                errorArray.splice(index, 1);
            }
        }catch(e){
            if(data.status = 'ZERO_RESULTS')
                return false;

            //on error call add marker function for same address and keep in Error ajax queue
            getBranchLatLng( address, 'Error' );
            if (index == -1) {
                errorArray.push( address );
            }
        }
    });

    //mentain ajax queue set
    queuCounter++;
    if( queuCounter == setLimit ){
        queuCounter = 0;
    }

});
}

现在的问题是,程序只停留在了 getBranchLatLng(),甚至没有进入 addForecastMarker(),尽管我已经成功地从 geocode 中打印出了一些经纬度。

一些返回给我的地址如下:

jquery.min.js:4 GET https://maps.googleapis.com/maps/api/geocode/json?key=&address= 400 ()

然后当我尝试扩展链接时,会出现以下情况:

error_message: "Invalid request. Missing the 'address', 'bounds', 'components', 'latlng' or 'place_id' parameter."
results :[]
status: "INVALID_REQUEST"

有没有解决返回“INVALID_REQUEST”地址到Promise父级的想法?
谢谢!

3
你的 getBranchLatLng 函数中没有使用 reject,可能会导致错误并使 Promise 停止。 - Amit Wagner
@AmitWagner 你的意思是把那个catch()块删掉吗? - QWERTY
现在向标记地图添加过滤器,以便我们解决错误。这应该跳过它。 https://jsfiddle.net/fLz2h661/2/ - Amit Wagner
1
首先,你缺少各种错误处理。如果在任何一个Promise.all()调用中的任何一个承诺失败,那么你的其他代码都不会运行。你需要在每个地方进行错误处理。这甚至可能向你展示这里发生了什么。这是一个忽略错误的糟糕的promise代码的典型例子。例如,如果你的ajax调用失败了呢?你什么也不做-父承诺既没有被拒绝也没有被解决,所以Promise.all()调用将永远等待。 - jfriend00
$.ajaxq是什么?看起来它确实返回一个Promise(或至少是jQuery deferred),你应该避免使用Promise构造反模式! - Bergi
显示剩余7条评论
1个回答

0

如果没有所有测试数据和您在代码中使用的未声明变量,就不可能生成工作代码。但总的来说,我的建议是,在ajax请求中添加catch块,并牢记您的getBranchLatLng Promise中不应有任何未resolvingrejecting的流程。

假设即使出现错误,您仍然希望解决您的getBranchLatLng,我已经按如下方式更新了您的代码,以便您的getBranchLatLng承诺中没有任何工作流程无法resolvereject

let promiseKey = Promise.all(
          result.map(el=>getBranchLatLng(el.branchAddress, el.branchName, el.amount))
        );

        var addedMarkers = promiseKey.then(
        markers => Promise.all(
          markers.map(marker => addForecastMarker(marker))
        )
        )
        .then(drawForecastHeatmap)
        .catch(functon(e) {
            //Do the error handling here
        });

function getBranchLatLng(address, branchName, total, queKey) {
return new Promise(function(resolve, reject) {
    var key = jQuery.rand(geoCodKeys);
    var url = 'https://maps.googleapis.com/maps/api/geocode/json?key='+key+'&address='+address+'&sensor=false';

    var qyName = '';
    if( queKey ) {
        qyName = queKey;
    } else {
        qyName = 'MyQueue'+queuCounter;
    }

    $.ajaxq (qyName, {
        url: url,
        dataType: 'json'
    }).done(function( data ) {
        var address = getParameterByName('address', this.url);
        var index = errorArray.indexOf(address);
        try{
            var p = data.results[0].geometry.location;
            var latlng = new google.maps.LatLng(p.lat, p.lng);

            var markerItem =
                {
                    'lat': p.lat,
                    'lng': p.lng,
                    'address': address,
                    'branchName': branchName,
                    'total': total,
                };
            console.log(markerItem);
            if (index > -1) {
                errorArray.splice(index, 1);
            }
            resolve(markerItem);

        }catch(e) {
                if (index == -1) {
                errorArray.push( address );
            }
                resolve({type: 'error', status: data.status});

        }
    })
    .catch(function(e) {
        resolve({type: 'error', status: data.status});
      //Instead of resolving with error code you can also reject the promise
      //reject(e);
    });

    //mentain ajax queue set
    queuCounter++;
    if( queuCounter == setLimit ){
        queuCounter = 0;
    }

  }
)};

function addForecastMarker(marker) {
console.log('adddddd markerssssss');
}

但这不是您可以直接使用的样板代码,以获得最终结果。当任何一个 Promise 失败时,您需要添加错误处理代码。为了帮助您,我已经使用 type: 'error' 解决了这些 Promise。在 promiseKey 的 then 块中,您必须读取它们并进行进一步的错误处理,并在调用 addForecastMarker 之前从数组中删除它们。

希望这有所帮助。


我明白了!非常感谢!我成功让它工作了。让我再测试几次! - QWERTY
太好了!很高兴能帮忙 :) - Sandip Ghosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接