Внутренняя функция обратного вызова JavaScript не выполнена - PullRequest
0 голосов
/ 12 октября 2018

У меня есть клиентское веб-приложение, которое берет csv-файл, анализирует его по разным типам данных, ищет что-то конкретное и выводит на экран таблицу с ответом.Функция поиска, возвращающая пустую строку.Это происходит потому, что его параметр поиска, возвращаемый функцией обратного вызова и помещаемый в lib, возвращает значение null.

Я вполне уверен, что это проблема с обратным вызовом, но я так много возился с порядкомя не уверен, что происходит в моем html ... Второй набор глаз будет оценен.

Желаемая серия событий

  1. fileToArray () дает нам массив
  2. search () ищет в массиве указанный элемент и возвращает строку в формате csv, содержащую найденное
  3. displayTable принимает эту строку в формате csv и выводит ее внужное место

Код

// jQuery call to fetch the client-side csv file - this works when called by itself.
const fileToArray = () => {
    console.log("fileToArray started.");
    $.get({
        url: CSV_LOCATION,
        dataType: "text",
        success: function (result) {
            console.log("splitting result by newline...");
            let csvLines = result.split("\n");
            console.log("split successful. generating array into retval ...");
            let retval = [];
            for (let i = 0; i < csvLines.length; i++) {
                // [0][0] is number [0][1] is class, [0][2] is unit, [0][3] is lesson
                retval[i] = csvLines[i].split(",");
            }
            console.log("success! Returning retval.");
            return retval;

            // callback(result);
            // return result;
        },
        failure: function (xhr, status, error) {
            console.log("ERROR: fileToString(): " + xhr + " ||| " + status + " ||| " + error);
            alert("ERROR: fileToString(): " + xhr + " ||| " + status + " ||| " + error);
        }
    })
};

// PRECONDITION: form is #search-params in index.js
//      > lib is the result of fileToArray()
// POSTCONDITION: result is a csv-format string to be passed to displayTable() in index.js
const search = (form, callback) => {
    console.log("search called...");
    // vvvvv The probable root of the problem vvvvv //
    let lib = callback;

    console.log(lib.length + " is lib's length.");

    let result = "";
    console.log("search nested for loop called...");
    for (let i = 0; i < lib.length; i++) {
        // check class
        console.log("checking class " + form.class.value + "...");
        if (lib[i][1] === form.class.value) {
            // check unit
            console.log("checking unit " + form.unit.value + "...");
            if (Number(lib[i][2]) === Number(form.unit.value)) {
                console.log("adding to result...");
                result += lib[i] + "\n";
            }
        }
    }
    console.log("search success! result: " + result.length + " characters");
    console.log(result);
    return result;
};
<!-- I'm almost 100% certain I've messed up the callback in this button,
but I still don't quite understand how... I've played with
displayTable(fileToArray(search(...))), but I don't quite know how it should go -->
<button class="btn btn-primary"
                onclick="displayTable(search(document.getElementById('search-params'), fileToArray), $('#card-display'))">
            Submit
</button>

То, что я пробовал

Я искал следующие сайты для вдохновения (ни один не помог):

  1. JavaScript - сексуальный
  2. JavaScript: передача параметров в функцию обратного вызова
  3. Функции обратного вызова JavaScript
  4. Передача аргументов в функции обратного вызова

В заключение

Это до боли очевидно, что я до сих пор неЯ не совсем понимаю обратные вызовы.Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Спасибо @kapantzak за вдохновение !!Оказывается, я использовал ужасные обратные вызовы.Согласно this , асинхронный стиль старой школы похож на

doSomething(function(result) {
  doSomethingElse(result, function(newResult) {
    doThirdThing(newResult, function(finalResult) {
      console.log('Got the final result: ' + finalResult);
    }, failureCallback);
  }, failureCallback);
}, failureCallback);

Итак, соответствующий код теперь выглядит так:

const fileToArray = (callback) => {
    // console.log("fileToArray started.");
    $.get({
        url: CSV_LOCATION,
        dataType: "text",
        success: function (result) {
            let csvLines = result.split("\n");
            let retVal = [];
            for (let i = 0; i < csvLines.length; i++) {
                // [0][0] is number [0][1] is class, [0][2] is unit, [0][3] is lesson
                retVal[i] = csvLines[i].split(",");
            }
            callback(retVal);
        },
        failure: function (xhr, status, error) {
            console.log("ERROR: fileToString(): " + xhr + " ||| " + status + " ||| " + error);
            alert("ERROR: fileToString(): " + xhr + " ||| " + status + " ||| " + error);
        }
    })
};
// =======

const search = (form, lib, callback) => {
    let result = "";
    let formClass = form.class.value.toLowerCase();
    let formUnit  = form.unit.value.toLowerCase();
    let formLesson = form.lesson.value.toLowerCase();
    for (let i = 0; i < lib.length; i++) {
        // check class
        if (lib[i][1].toLowerCase() === formClass) {
            // check unit
            if (Number(lib[i][2].toLowerCase()) === Number(formUnit)) {
                result += lib[i] + "\n";
            }
        }
    }
    console.log(result);
    callback(result);
};
        <button class="btn btn-primary"
                onclick="fileToArray(function(result) {
                  search(document.getElementById('search-params'), result, function(newResult) {
                    displayTable(newResult, $('#card-display'));
                  });
                });">
            Submit
        </button>

Это исправило ошибки и заставило мой поиск и отображение функционировать должным образом.

0 голосов
/ 12 октября 2018

Вы можете использовать async / await

const displayTable = async () => {
    let arrayFromFile = await fileToArray(); // fileToArray executes and assigns the returned value when it completes
    let searchedData = search(form, arrayFromFile);
    // Display the table
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...