【问题标题】:Returning data from my JavaScript function从我的 JavaScript 函数返回数据
【发布时间】:2017-04-24 00:57:23
【问题描述】:

我在获取我请求正确显示的数据时遇到问题,它被显示为未定义。

 fetch(url)
.then(res => res.json())
.then((manager) => {
/* console.log(manager); */ 
    for (i in manager.data){
        var row = $('<div id="Data">' + '<br>' + getLogo(manager, i) + '<br>'
                + '<br>' + '<p1>' + getName(manager, i) + '</p1>'   
                + getAdd1(manager, i) + getAdd2(manager, i) + getAdd3(manager, i) 
                + getCity(manager, i) + getPcode(manager, i) 
                + '<br>' + getCountry(manager, i) + '<br>' 

我的问题是调用 getCountry

                + '<br>' + getWeb(manager, i) + '<br>' 
                + '<br>' + getPhases(manager, i) 
                + '<br>' + getPspon(manager, i) 
                + '<br>' + getOspon(manager, i) + '<br>'
                + '<br>' + getDesc(manager, i) + '<br>' 
                + '<br>' + '</div>' + '<br>');

        $('#Results').append(row);
    }           
})
};

经过一些研究,我认为问题在于 getCountry 方法太长了,它会继续执行其余代码并将其显示为未定义。

然后我遇到了 Promise 并尝试将其添加到函数中,但现在 html 页面只显示 [object Promise]。 getCountry 函数如下所示,在添加 Promise 代码之前是相同的。

这就是我想要达到的目标

检查是否有地址,然后检查国家代码。将 3 位数字国家代码分配给国家。然后将包含 ISO 3166 数据处理的 JSON 加载到可搜索对象中。搜索对象以匹配存储在国家/地区中的值。然后将匹配对象中的名称字段分配给result,然后将其返回以显示在地址的末尾。

function getCountry(manager, i){
    return new Promise(function(resolve, reject) {
        if(manager.data[i].attributes.addresses[0] != null && manager.data[i].attributes.addresses[0].country != null){
            var country = manager.data[i].attributes.addresses[0].country;
            var c = country.toString();
            let url = 'http://data.okfn.org/data/core/country-codes/r/country-codes.json';
            fetch(url)
            .then(res => res.json())
            .then((data) => {
            console.log(data);
            console.log(manager);
                        for(var i=0, length=data.length; i<length; i++){
                        if(data[i].M49 === c){
                            var result = data[i].name;
                            console.log(result);
                            Promise.resolve(result);

                        }
                    }
            })
        }
        else {
            var reason = " ";
            Promise.reject(reason);
        }
    }
    );
}

我哪里错了?

使用@Zohaib Ijaz 建议更新代码

fetch(url)
.then(res => res.json())
.then((manager) => {
/* console.log(manager); */ 
    for (i in manager.data){
        /* use a Promise in order to receive the result for the below function */
        getCountry(manager, i).then((cm)=> {
        var row = $('<div id="Data">' + '<br>' + getLogo(manager, i) + '<br>'
                + '<br>' + '<p1>' + getName(manager, i) + '</p1>'   
                + getAdd1(manager, i) + getAdd2(manager, i) + getAdd3(manager, i) 
                + getCity(manager, i) + getPcode(manager, i) 
                + '<br>' + cm + '<br>'
                + '<br>' + getWeb(manager, i) + '<br>' 
                + '<br>' + getPhases(manager, i) 
                + '<br>' + getPspon(manager, i) 
                + '<br>' + getOspon(manager, i) + '<br>'
                + '<br>' + getDesc(manager, i) + '<br>' 
                + '<br>' + '</div>' + '<br>');

        $('#Results').append(row);
        });
}
});
}

getCountry 函数

function getCountry(manager, i){
    return new Promise(function(resolve, reject) {
    if(manager.data[i].attributes.addresses[0] != null && manager.data[i].attributes.addresses[0].country != null){
        var country = manager.data[i].attributes.addresses[0].country;
        var c = country.toString();
        let url = 'http://data.okfn.org/data/core/country-codes/r/country-codes.json';
        fetch(url)
        .then(res => res.json())
        .then((data) => {
                    for(var i=0, length=data.length; i<length; i++){
                        if(data[i].M49 === c){
                        var result = data[i].name;
                        /* console.log(result); */
                        resolve(result);
                        }
                        else {
                        var reason = "";
                        reject(reason);
                        }
                    }
        })
    }
    else {
        var reason = "";
        reject(reason);
    }

}
);
}

这是我在 Chrome 控制台中看到的(24 次)

未捕获(承诺)test.html:1

【问题讨论】:

  • 问题不在于函数长时间运行;就是函数是异步的。调查 Promise(甚至是 Futures/Tasks)是对的,但我认为你需要更多地阅读它们的工作原理以及如何使用它们。

标签: javascript jquery json javascript-objects


【解决方案1】:

我注意到你打电话给Promise.resolve(result);当您在函数的开头实例化 Promise 时,您向它传递了一个带有两个参数的函数,resolvereject。这些是您应该用来“结束”您的 Promise 的东西,因此将它们更改为 resolve(result)reject(reason) 应该可以让您的 Promise 正确解决。

也就是说,Promise 的意义在于说“做这个,完成后,.then 做这件事”。所以你需要像

getCountry(manager, i).then(function(result) {
    // result is whatever you passed into resolve() in getCountry
    // everything in here is done after getCountry finishes running
    // and returns a value 
}, function(rejection) {
    // rejection is whatever you passed into reject() in getCountry
    // this only happens if things didn't work
}

我不确定 Promises 是否会起作用,因为您是在连接中间调用该函数。如果您的其他函数进行异步调用,您可能会考虑将所有异步函数重写为 Promise,然后使用 Promise.all() 等待它们全部解析,然后再将它们连接到 HTML。像这样的

var p1 = getLogo(manager, i);
var p2 = getName(manager, i);
var p3 = getAdd1(manager, i);
...

Promise.all([p1, p2, p3]).then(function(results) {
    results.join('<br>')
    // Whatever else you want to happen once all the functions are finished.
})

【讨论】:

    【解决方案2】:

    getCountry 不是同步函数调用。您需要等待响应。

    fetch(url)
    .then(res => res.json())
    .then((manager) => {
    /* console.log(manager); */ 
        for (i in manager.data){
            getCountry(manager, i).then((cm)=> {
              // Add other values as well. 
              var row = $('<br>' + cm + '<br>');
              $('#Results').append(row);
            });   
        }
     });
    

    【讨论】:

    • 我已经使用了这种方法,但是我收到了多个未捕获的异常,我该如何处理它们?
    • @Bob 你能显示你更新的代码和异常日志吗?
    • 我有 2 页数据正在使用分页显示。第 1 页 = 24 个结果,第 2 页 = 8 个结果。当我的代码到达第 1 页上的索引 23 时,对象没有存储地址,而是返回我想要的空字符串。它返回英国的结果,就好像它确实有一个地址,并在我的网页上显示了 24 次
    猜你喜欢
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多