承诺排序

时间:2019-10-23 12:50:47

标签: javascript ajax asynchronous promise

在此函数中,我尝试运行2个不同的ajax请求(3个选项,根据if语句仅运行2个)。 addDep()addCust()函数都在其中具有ajax请求,并发送了一个url。但是,我需要该ajax函数运行并完成,然后在.then函数中的代码在运行后被调用。现在,代码正在运行,但是具有空值,因为它没有从ajax函数返回data1或data2。我该如何解决?

function builder(){
    var beforeDate = dateConv(document.getElementById('Before').value);
    var afterDate = dateConv(document.getElementById('After').value);

    var url = "http://localhost:8181/GRAIN/grain_map?start="
    url += afterDate;
    url += "&end=";
    url += beforeDate;
    url += "&attributes=DATE-SHIPPED+DESTINATION-NAME+DESTINATION";

    ajaxReq(url).then(function (jsonString) {
        for (i=0; i < jsonString.grain_map.length; i++){
            destinationArray.push(jsonString.grain_map[i].DESTINATION);
        }

        for (i = 0; i < destinationArray.length; i++){
            if (destinationArray[i] == ""){
                continue;
            }
            if (destinationArray[i].length == 3 || destinationArray[i].length == 2){
                var destCode = destinationArray[i];
                addDep(destCode).then(function (data1) {
                    var address = "";
                    var depArray = data1.dep_address[0].ADDRESS;
                    for(i = 0; i < depArray.length; i++){
                        address += data1.dep_address[0].ADDRESS[i] + " ";
                    }
                    addressArray.push(address);
                }).catch(function (err) {
                    console.error(err);
                });

            }else if (destinationArray[i].length == 6){
                var destCode = destinationArray[i];
                addCust(destCode).then(function (data2) {
                    var address = "";
                    var depArray = data2.customer_address[0].ADDRESS;
                    for(i = 0; i < depArray.length; i++){
                        address += data2.customer_address[0].ADDRESS[i] + " ";
                    }
                    addressArray.push(address);
                }).catch(function (err) {
                    console.error(err);
                });
            }
        }
    }).catch(function (err) {
        console.error(err);
    });
}

1 个答案:

答案 0 :(得分:0)

现状:

  • builder()返回undefined-它应返回Promise。
  • 外部的回调返回undefined-它应返回Promise。
  • 然后是两个内部then的回调返回undefined-它们可以(并且应该)返回String。
  • addDep()addCust()返回的内部承诺未汇总-没有Promise.all()
  • 有两个神秘的,未声明的数组destinationArrayaddressArray,这使我有些guess测。

数组方法.map().filter().join()可以简化代码

function builder() {
    var beforeDate = dateConv(document.getElementById('Before').value);
    var afterDate = dateConv(document.getElementById('After').value);
    var url = `http://localhost:8181/GRAIN/grain_map?start=${afterDate}&end=${beforeDate}&attributes=DATE-SHIPPED+DESTINATION-NAME+DESTINATION`;
    return ajaxReq(url)
//  ^^^^^^
    .then(jsonString => {
        var promises = jsonString.grain_map
        .map(item => {
            var destcode = item.DESTINATION || '';
            switch(destCode.length) {
                case 2:
                case 3:
                    return addDep(destCode)
                //  ^^^^^^
                    .then(data => data.dep_address[0].ADDRESS.join(' '))
                    .catch(error => `addDep: ${destCode}: ${error.message}`); // inject message in place of missing address
                break;
                case 6:
                    return addCust(destCode)
                //  ^^^^^^
                    .then(data => data.customer_address[0].ADDRESS.join(' '))
                    .catch(error => `addCust: ${destCode}: ${error.message}`); // inject message in place of missing address
                break;
                default:
                    return null;
                //  ^^^^^^
            }
        })
        .filter(p => !!p); // filter out any nulls leaving just Promises
        return Promise.all(promises);
    });
}

返回呼叫者...

builder()
.then(addressArray => {
    // do something with addressArray.
})
.catch(err => {
    console.error(err);
    throw error; // unless this promise chain is at the topmost level of an event thread.
});

注意:

  • 问题的中间destinationArray完全消失了-从来没有必要。
  • Arrow functions用于紧凑。
  • 在这些捕获处理程序中执行的操作完全取决于您要执行的操作。如上文所述,错误消息将代替每个丢失的地址插入。您也可以选择重新引发错误,并允许Promise.all(promises)返回的Promise在遇到第一个错误时遵循其错误路径。
  • addressArray现在由builder()返回的Promise交付。
  • 开关/外壳结构不是绝对必要的,但可以使代码整洁(IMHO)。