为啥我的 console.log 没有在这里输出任何东西? [复制]

Posted

技术标签:

【中文标题】为啥我的 console.log 没有在这里输出任何东西? [复制]【英文标题】:Why is my console.log not outputting anything here? [duplicate]为什么我的 console.log 没有在这里输出任何东西? [复制] 【发布时间】:2021-05-17 04:43:09 【问题描述】:

所以我尝试使用数组上的 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]]: ""

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

【问题讨论】:

为什么不使用 XHR 而不是 $.json 你的意思是使用console.log(await getAPIResults),而不是await console.log(getAPIResults) 顺便说一句,在将 jQuery deferreds 包装在真正的 Promise 中时,您可以避免使用 Promise constructor antipattern 和 just write Promise.resolve($.json(…)) 【参考方案1】:

您正在等待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

【讨论】:

感谢您的回复。我不明白为什么 array.push 不会将任何数据推送到我的数组。你的意思是我应该在xmlHttp.send 之后使用.then(res =&gt; ) 吗? (我刚试过,没用) 另外 - 我的 console.log 仍然没有做任何事情 @AdamCole:控制台有错误吗?如果data 是一个数组,那么等待getAPIResults 至少应该遍历该数组并将其元素记录到控制台。特别注意data的结构。它是一个数组,还是一个具有 property(也称为data)的对象,它是一个数组?您需要调试才能找出答案。至于 AJAX 请求,我在回答中链接到的问题有一些示例,说明如何将 XMLHttpRequest 包装在 Promise 中。虽然你为什么不像以前那样使用$.getJSON 呢?然后你可以追加.then() @AdamCole:我已经用更多代码更新了答案,展示了您如何等待在getAPIResults 中发出的一系列 AJAX 请求。 您的编辑修复了我的代码,谢谢!现在我已经达到了我在 Fetchify API 上免费试用的限制,所以现在这段代码对我来说几乎没用了?‍♂️ 谢谢你的帮助!

以上是关于为啥我的 console.log 没有在这里输出任何东西? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 console.logs 没有被写入?

为啥 console.log 从日志中排除我的零?

Console.log 语句在 Jest 中不输出任何内容

在 TypeScript 中是无效的。为啥我从 console.log 得到结果?

使用 nodejs/npm start 在哪里查看 console.log 输出?

为啥这个异步函数没有异步运行?