【问题标题】:Why is javascript callback function not executing?为什么javascript回调函数没有执行?
【发布时间】:2021-01-06 08:57:24
【问题描述】:

有人可以解释为什么 loadData(symbol) 之后的回调函数没有被调用吗?我有这个功能:

    function plotChart(symbol) {
        alert("symbol: " + symbol);
        var data = loadData(symbol, function(){
            console.log("data: ",data);
        });
    }

我希望 log.console 在 loadData 完成后执行,但没有任何输出。

如果重要,这里是 loadData 函数。

    function loadData(symbol) {
    count = 0;
    quotes = [];
    $.getJSON("http://localhost:8080/springboot-crud-rest/api/v1/quotes-between?symbol=IBM&startDate=2020-01-01&endDate=2020-09-30", function(data) {
        data.forEach(function(item){
            var quote = {};
            quote.date   = item.id.date.substring(0,10);
            quote.open   = item.open;
            quote.high   = item.high;
            quote.low    = item.low;
            quote.close  = item.close;
            quote.volume = item.volume;
            quotes.push(quote); //put quote in array
        });
        console.log("quotes: ",quotes);  
        return quotes;
    });
}

在这里,console.log 成功正确打印出引号。

编辑: 根据@Aluan,我将代码更改为如下所示:

    function plotChart(symbol) {
        loadData(symbol).then(function(data) {
            console.log("data: ", data);
        });
    }

    function loadData(symbol) {
        quotes = [];
        $.getJSON("http://localhost:8080/springboot-crud-rest/api/v1/quotes-between?symbol=" +symbol +"&startDate=2020-01-01&endDate=2020-09-30") 
            .then(function (data) {
            const quotes = data.map(function(item) {
                return {
                    date: item.id.date.substring(0,10),
                    open: item.open,
                    high: item.high,
                    low : item.low,
                    close: item.close,
                    volume: item.volume
                };
            });
            console.log("quotes: ",quotes);  
            return quotes;
        });
    }

但现在我遇到了错误: 未捕获的类型错误:无法读取未定义的属性“then” 在 plotChart (moneymachine.html:120) 在 HTMLTableRowElement 处。

第 120 行是loadData(symbol).then(function(data) {

【问题讨论】:

    标签: javascript jquery json


    【解决方案1】:

    loadData 的定义对于理解原因至关重要。

    给定

    function loadData(symbol) {
        count = 0;
        quotes = [];
        $.getJSON("http://localhost:8080/springboot-crud-rest/api/v1/quotes-between?symbol=IBM&startDate=2020-01-01&endDate=2020-09-30", function (data) {
            data.forEach(function (item) {
                var quote = {};
                quote.date   = item.id.date.substring(0, 10);
                quote.open   = item.open;
                quote.high   = item.high;
                quote.low    = item.low;
                quote.close  = item.close;
                quote.volume = item.volume;
                quotes.push(quote); //put quote in array
            });
            console.log("quotes: ", quotes);  
            return quotes;
        });
    }
    

    我们可以看到它定义了一个参数symbol。你可以在调用它时传递额外的参数,但它显然不使用它们。

    当你写作时

    var data = loadData(symbol, function () {
        console.log("data: ", data);
    });
    

    第二个参数被忽略。

    这是一个loadData 的示例,它将接受并使用作为回调的第二个参数。

    function loadData(symbol, callback) {
        count = 0;
        quotes = [];
        $.getJSON("http://localhost:8080/springboot-crud-rest/api/v1/quotes-between?symbol=IBM&startDate=2020-01-01&endDate=2020-09-30", function(data) {
            data.forEach(function(item){
                var quote = {};
                quote.date   = item.id.date.substring(0, 10);
                quote.open   = item.open;
                quote.high   = item.high;
                quote.low    = item.low;
                quote.close  = item.close;
                quote.volume = item.volume;
                quotes.push(quote); //put quote in array
            });
            callback(data) // here
            console.log("quotes: ", quotes);  
        });
    }
    

    但是,loadData 的这个定义充其量是次优的。它应该利用 jQuery 的 $.getJson 返回的 thenable,使代码更清晰。

    function loadData(symbol) {
        return $.getJSON("http://localhost:8080/springboot-crud-rest/api/v1/quotes-between?symbol=IBM&startDate=2020-01-01&endDate=2020-09-30")
            .then(function (data) {
                const quotes = data.map(function (item) {
                    return {
                        date: item.id.date.substring(0, 10),
                        ...item
                    };
                });
                console.log("quotes: ", quotes);
                return quotes;
            });
    }
    

    消费

    loadData('something').then(function (data) {
        console.log("data: ", data);
    });
    

    【讨论】:

    • 我知道符号参数现在没有被使用。但是你是说因为没有使用,所以回调函数被忽略了?我没有发现深度缩进的代码使它更清晰。对我来说正好相反。我也不明白回调(数据)的作用或为什么需要它。但我会试一试。谢谢阿銮!
    • 我更改了我的代码,使其看起来像您在原始帖子的编辑中更新的代码,但现在遇到了一个新问题。
    • 我无法让您的第二个示例工作,但我确实让第一个工作。我现在明白了。我将一个函数作为参数传递,但在完成后未能从 loadData 调用该函数。我原以为这会自动发生。只有在你说回调(数据)的地方,我才说回调(引号)。那行得通。
    • @user3217883 我查看了您对问题的编辑。当你复制第二个版本时,你错过了一些东西。你忘了回报。这就是它失败的原因
    • 啊,好的,我现在明白了。无论如何,我保留了第一个版本。第二个我太难理解了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 2021-05-22
    • 2013-02-16
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多