weixin_33698043 2019-10-23 12:50 采纳率: 0%
浏览 46

承诺排序

In this function, I am trying to run 2 different ajax requests (3 options, only 2 will run depending on if statements). addDep(), and addCust() functions both have an ajax request in them and get sent an url. However, I need that ajax function to run and complete before the code in the .then function being called after it runs. Right now the code runs but has null values because it hasn't got data1 or data2 back from the ajax function. How do I fix this?

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条回答 默认 最新

  • weixin_33671935 2019-11-01 00:32
    关注

    As it stands:

    • builder() returns undefined - it should return Promise.
    • the outer then's callback returns undefined - it should return Promise.
    • the two inner thens' callbacks return undefined - they could (and should) return String.
    • the inner Promises returned by addDep() or addCust() are not aggregated - there's no Promise.all().
    • there are two mysterious, undeclared arrays, destinationArray and addressArray, resulting in some guesswork on my part.

    Array methods .map(), .filter() and .join() allow the code to be simplified

    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);
        });
    }
    

    Back in the caller ...

    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.
    });
    

    Notes:

    • The question's intermediate destinationArray disappears completely - it was (probably) never necessary.
    • Arrow functions are used for compactness.
    • What you do in those catch handlers depends on exactly what you want. As written above, an error message is injected in place of each missing address. You could alternatively choose to re-throw the error and allow the Promise returned by Promise.all(promises) to follow its error path on first error encountered.
    • addressArray is now delivered by the Promise returned by builder().
    • the switch/case structure is not absolutely necessary but makes for neater code (IMHO).
    评论

报告相同问题?

悬赏问题

  • ¥200 csgo2的viewmatrix值是否还有别的获取方式
  • ¥15 Stable Diffusion,用Ebsynth utility在视频选帧图重绘,第一步报错,蒙版和帧图没法生成,怎么处理啊
  • ¥15 请把下列每一行代码完整地读懂并注释出来
  • ¥15 pycharm运行main文件,显示没有conda环境
  • ¥15 寻找公式识别开发,自动识别整页文档、图像公式的软件
  • ¥15 为什么eclipse不能再下载了?
  • ¥15 编辑cmake lists 明明写了project项目名,但是还是报错怎么回事
  • ¥15 关于#计算机视觉#的问题:求一份高质量桥梁多病害数据集
  • ¥15 特定网页无法访问,已排除网页问题
  • ¥50 如何将脑的图像投影到颅骨上