arr
说,我有一个数组,我需要对其进行迭代。
到目前为止我尝试过的事情:
arr.forEach((rack) => {
request.post({
headers: {'content-type' : 'application/x-www-form-urlencoded'},
url: 'https://example.com/render',
body: "target=foobar"
}, function(error, response, data){
if (error) {
console.err(error);
} else {
console.log(JSON.stringify(data, null, 4));
}
});
});
我没有输出,也没有错误。
奖励问题:我可以从全局范围内的帖子中返回一个值吗?
答案 0 :(得分:1)
问题的第一部分是因为请求是异步的,因此您需要完成forEach循环并在调用完成之前退出。
对于第二部分,您可以使用promise基本等待查询结果。代码
function getPromise(url) {
return new Promise((resolve, reject) => {
request.post({
headers: {'content-type' : 'application/x-www-form-urlencoded'},
url: 'https://example.com/render',
body: "target=foobar"
}, function(error, response, data) {
if(error) {
reject(error)
} else {
resolve(JSON.stringify(data, null, 4))
}
})
})
}
var promiseArray = arr.map((rack) => getPromise(rack))
Promise.all(promiseArray).then((value) => {
console.log('I am done');
})
将是您想要的。您可以分配回全局范围值(尽管不建议这样做)
答案 1 :(得分:1)
一种解决方案是将其包装在promise中:
for rack of arr {
try {
const result = await new Promise((res, rej) => {
request.post({
headers: {'content-type' : 'application/x-www-form-urlencoded'},
url: 'https://example.com/render',
body: "target=foobar"
}, function(error, response, data){
if (error) {
rej(error);
console.err(error);
} else {
res(data);
}
});
});
console.log(JSON.stringify(result, null, 4));
} catch(err) {
console.log(err);
}
}
答案 2 :(得分:1)
forEach
是严格同步的,并且通常已过时,因为它不支持生成器,而循环语句则支持async..await
。可以使用async..await
和request-promise
(它们是request
的官方承诺副本)来完成:
// within async function
for (const rack of arr) {
try {
const data = await request.post({
headers: {'content-type' : 'application/x-www-form-urlencoded'},
url: 'https://example.com/render',
body: "target=foobar"
});
console.log(JSON.stringify(data, null, 4));
} catch (error) {
console.err(error);
}
}
由于请求彼此不依赖,因此可以与Promise.all
并行执行。
我可以从全局范围内的帖子中返回值吗?
这是this infamous problem的特例。异步调用中的值不能以同步方式使用,这会将异步控制流扩展到所有调用堆栈,可能一直扩展到入口点:
(async () => {
const result = await asyncFn();
})().catch(console.error)