微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的 console.log 在这里没有输出任何内容?

如何解决为什么我的 console.log 在这里没有输出任何内容?

所以我尝试使用数组上的 foreach 循环向 API 发出请求。该数组包含放入请求中的字符串列表

var myHeaders = new Headers();
myHeaders.append("Content-Type","application/x-www-form-urlencoded");

var urlencoded = new URLSearchParams();
urlencoded.append("","");

var requestOptions = {
  method: 'POST',headers: myHeaders,body: urlencoded,redirect: 'follow'
};

var array = [];
var data = [];

var importdata =  new Promise((resolve,reject) => {
    $.getJSON('name of json.json')
    .then(response => {
        data = response;
        resolve(response)
    })
    .catch(err => {
        reject(err)
    })
})

var getAPIResults = new Promise((resolve,reject) => {
    var xmlHttp = new XMLHttpRequest();
    data.forEach((element) => {
        console.log(element) // This isn't being outputted into the console,even though 'data' array has elements after running 'importdata'
        xmlHttp.open( "GET",'http://api.com/json/apiroute?key=xxxx-xxx-xxxx&dataitem='+element,true );
        xmlHttp.send( null );
        array.push(xmlHttp.responseText)
    })
    resolve(xmlHttp.responseText)
})


async function main () {
    await importdata
    await console.log(data)
    await console.log(getAPIResults)
}

main()

我在未记录数据的地方添加评论

控制台如下所示:

{Data: {…}}
Data:
   data: (1030) [expected data elements]
   __proto__: Object
   __proto__: Object

Promise {<fulfilled>: ""}
   __proto__: Promise
   [[PromiseState]]: "fulfilled"
   [[PromiseResult]]: ""

在运行 data 时,当然应该有很长的元素列表(getAPIResults 数组大约有 1000 个元素)?

解决方法

您正在等待 console.log(非异步),但未等待 getAPIResults Promise(异步)。正如您在等待 importdata 时所做的那样,您还需要等待 getAPIResults

await importdata;
console.log(data);
console.log(await getAPIResults);

虽然看起来 getAPIResults 本身存在更多问题。它在内部发送 AJAX 请求,这些请求也是异步的,但它试图立即使用它们的响应。您需要继续重复 awaiting promises 的模式,或者使用回调。

至少 console.log(element) within getAPIResults 会按照问题中的要求执行您的要求。但是您的下一个问题将是 array.push(xmlHttp.responseText) 没有将数据推送到数组,而 resolve(xmlHttp.responseText) 没有从承诺中解决任何问题。 (难道你不想解析到数组,而不仅仅是最后一个 API 结果吗?)


编辑:关于在 getAPIResults 中发生的 AJAX 操作,您希望像处理 importdata 一样异步处理它们。事实上,为什么不像您已经使用的那样使用 $.getJSON?也许是这样的:

var getAPIResults = new Promise((resolve,reject) => {
    var promises = [];
    data.forEach((element) => {
        console.log(element);
        promises.push(
            $.getJSON('http://api.com/json/apiroute?key=xxxx-xxx-xxxx&dataitem='+element)
            .then(response => {
                array.push(response);
            });
        );
    });
    Promise.all(promises).then(() => {
        resolve(array);
    });
});

这里的想法是循环遍历您拥有的数据数组,为每个数据调用一个 AJAX 请求。 $.getJSON 返回一个 Promise,因此您将所有这些 Promise 添加到一个数组中。然后使用 Promise.all 等待所有这些承诺,当它们完成时,将 getAPIResults 解析为结果数据。

顺便说一句,如果这是一个选项,您可能希望开始使用 async/await 语法。这将清除很多问题,并使代码更易于遵循。与其让 getAPIResults 之类的东西成为 Promise,不如让它成为一个 function,恰好是 async。一些简单的事情:

var getAPIResults = async () => {
    const result = [];
    for (const element of data) {
        // I don't think jQuery's AJAX functions return actual promises.
        // So I've wrapped it in one here.  Which is inelegant,but should work.
        // If they DO return actual promises these days,unwrap this.
        // It's worth testing both approaches for your needs.
        const response = await new Promise(resolve => {
            $.getJSON('http://api.com/json/apiroute?key=xxxx-xxx-xxxx&dataitem='+element)
            .then(json => {
                resolve(json);
            });;
        });
        result.push(response);
    }
    return result;
};

然后使用该函数将是:

console.log(await getAPIResults());

您还会发现向函数传递值和从函数返回值比依赖全局变量要干净得多。请注意此版本如何不推送到全局 array 变量,而只是返回预期的数组。您还可以使 importdata 成为一个返回其结果的函数,并将该结果作为函数参数传递给 getAPIResults

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。