如何解决为什么我的 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 举报,一经查实,本站将立刻删除。