JavaScript回调内部函数未执行

时间:2018-10-12 14:11:54

标签: javascript jquery html callback

我有一个客户端Web应用程序,该应用程序获取一个csv文件,将其解析为各种数据类型,搜索特定内容,并在屏幕上显示带有答案的表格。搜索函数返回空字符串。发生这种情况是因为其搜索参数(由回调函数返回并放入lib中)返回null。

我相当确定这是一个回调问题,但是我已经弄乱了命令的顺序,所以我不确定html中的内容将如何发展……第二组眼睛将不胜感激。 / p>

所需的一系列事件

  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 is Sexy
  2. JavaScript: Passing parameters to a callback function
  3. JavaScript Callback Functions
  4. Passing arguments to callback functions

摘要

很明显,我仍然不完全了解回调。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

您可以使用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
};

答案 1 :(得分:-1)

感谢@kapantzak的启发!!原来,我使用的回调非常糟糕。根据{{​​3}},老式的异步风格类似于

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>

这纠正了错误,并导致我的搜索和显示正常运行。