Как добавить обещание вернуть так, чтобы $ .when и .then работали правильно? - PullRequest
0 голосов
/ 17 июня 2019

У меня проблема, связанная с асинхронным выполнением Javascript. Я пытаюсь установить значение переменной с помощью функции, а затем сразу же использовать эту переменную в вызове функции. Я хочу реализовать JQuery .when и .hen для решения этой проблемы, но у меня возникают проблемы с тем, как выполнить обещание, необходимое для .then, чтобы знать, когда начинать выполнение.

Вот что у меня есть:

function addSerialNumber(item_id) {
    var serialNumberList;
    var serialNumber = $("serial-number").val();

    $.when(serialNumberList = addSerialFunc(item_id, serialNumber))
    .then(alert("Serial number successfully added."), 
        insertTransaction(item_id, serialNumberList));
}

function addSerialFunc(item_id, serialNumber) {
    var serialNumberList = new Array();

    $.ajax({
        type: "post",
        url: "someRandom.jsp",
        data: {wsFunction: "Insert", item_id: item_id, serialNumber: serialNumber},
        async: false
    }).done(function(xml){
        $(xml).find("Item").each(function() {
            insert_id = ($(this).find("SendBack_CD").text());

            if (!runError(insert_id, item_id)) {
                //Fail
            } else {
                //Success
                serialNumberList.push(insert_id);
            }
        })
    }).fail(function(jqXHR, textStatus, errorThrown) {
        console.log("Error occured! Type: " + textStatus + " HTTP Error Thrown: " + errorThrown);
    });

    return serialNumberList;
}

Я пытаюсь создать serialNumberList путем вызова addSerialFunc (), а затем использовать serialNumberList в качестве аргумента для insertTransaction (). Иногда это работает, но я периодически получаю

Uncaught TypeError: Cannot read property 'substring' of undefined

потому что он пытается выполнить insertTransaction () до того, как serialNumberList будет заполнен addSerialFunc ().

Как я могу реализовать обещание в addSerialFunc (), чтобы .then знал, когда начинать выполнение?

1 Ответ

1 голос
/ 17 июня 2019

Несколько выпусков:

  • В addSerialFunc вы возвращаете значение синхронно, но оно будет заполнено позже, когда ответ поступит от асинхронного вызова ajax. Вместо этого вы должны вернуть обещание , возвращенное на $.ajax.

  • Вы вызываете alert немедленно, вместо передачи функции обратного вызова на then.

  • вы передаете второй аргумент then, который снова не является функцией по той же причине, что и в предыдущем пункте. Но также и второй аргумент должен быть функцией, когда обещание отклоняется.

Итак, это должно работать лучше - предполагается, что jQuery версии 3.x:

function addSerialNumber(item_id) {
    var serialNumberList;
    var serialNumber = $("serial-number").val();

    // *** $.when is not needed
    addSerialFunc(item_id, serialNumber) // *** start with the returned promise
    .then(function (serialNumberList) { // pass a function(!), which gets the value as argument
        alert("Serial number successfully added."); 
        insertTransaction(item_id, serialNumberList);
    }).catch(function (err) { // better to also have a `catch` call here
        console.log(err);
        console.log("because of error, no transaction is inserted");
    });
}

function addSerialFunc(item_id, serialNumber) {    
    return $.ajax({
//  ^^^^^^
        type: "post",
        url: "someRandom.jsp",
        data: {wsFunction: "Insert", item_id: item_id, serialNumber: serialNumber}
        /* drop the `async` property */
    }).then(function(xml){
 //    ^^^^
        var serialNumberList = new Array(); // *** define here
        $(xml).find("Item").each(function() {
            var insert_id = ($(this).find("SendBack_CD").text());
    //      ^^^^ make sure to always define the scope of your variables!
            if (!runError(insert_id, item_id)) {
                //Fail
                throw "Some error occurred"; // *** adapt message here
                ^^^^^^
            } else {
                //Success
                serialNumberList.push(insert_id);
            }
        });
        return serialNumberList; // *** return!!!!
    }).catch(function(jqXHR, textStatus, errorThrown) {
 //    ^^^^^
        console.log("Error occured! Type: " + textStatus + " HTTP Error Thrown: " + errorThrown);
        throw errorThrown; // *** cascade the error
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...