Последовательность обещаний - PullRequest
0 голосов
/ 23 октября 2019

В этой функции я пытаюсь запустить 2 разных ajax-запроса (3 варианта, только 2 будут выполняться в зависимости от операторов if). Функции addDep() и addCust() содержат запрос ajax и получают URL-адрес. Однако мне нужно, чтобы эта функция ajax запускалась и выполнялась до вызова кода в функции .then после ее запуска. Прямо сейчас код выполняется, но имеет нулевые значения, потому что он не получил data1 или data2 обратно из функции ajax. Как мне это исправить?

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 голосов
/ 01 ноября 2019

В таком виде:

  • builder() возвращает undefined - он должен вернуть Promise.
  • обратный вызов внешнего тогда возвращает undefined - он должен вернуть Promise.
  • обратные вызовы двух внутренних тогда возвращают undefined - они могут (и должны) возвращать строку.
  • внутренние Обещания, возвращаемые addDep() или addCust(), не агрегируются - нет Promise.all().
  • есть два загадочных необъявленных массива, destinationArray и addressArray, что приводит к некоторым догадкам с моей стороны.

Методы массива .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 полностью исчезает - это было (вероятно) никогда не нужно.
  • Функции стрелок являютсяиспользуется для компактности.
  • То, что вы делаете в этих обработчиках catch, зависит именно от того, что вы хотите. Как написано выше, сообщение об ошибке вводится вместо каждого пропущенного адреса. В качестве альтернативы вы можете выбрать повторную выдачу ошибки и позволить Обещанию, возвращенному Promise.all(promises), следовать по пути ошибки при первой обнаруженной ошибке.
  • addressArray теперь доставляется Обещанием, возвращаемым builder().
  • структура переключателя / корпуса не является абсолютно необходимой, но требует более аккуратного кода (IMHO).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...