gpt4 book ai didi

javascript - 真正同步运行多次 fetch

转载 作者:行者123 更新时间:2023-12-03 01:51:58 25 4
gpt4 key购买 nike

我见过各种使 fetch 看起来同步的解决方案,例如使用await,但是它们必须包装在异步函数中,因此整个事情不是同步的。

我需要运行 fetch x 次,并按照开始的顺序完成每次迭代。如果我在 fetch 之后使用 .then ,它会在每个 fetch 实例之后运行,但结果(包括 .then 运行的函数的结果)将按响应顺序返回,因此列表按 a-z 顺序获取的 url 在输出时可能会部分随机返回,这是 Not Acceptable 。

我尝试使用带有 async: false 的 jquery ajax,虽然这使输出与输入保持顺序 - 当它成功运行时 - 它会在错误时无限期卡住,并且它的超时值在同步中不起作用模式。

我们似乎可以选择以潜在的随机顺序获取多个连续的 url,或者我们可以按顺序获取它们,使用同步模式下的 jquery ajax/XMLHTTPRequest,但当 URL 时会卡住浏览器超时,而我们设置的用于中止尝试检索 url 的超时值将被忽略。

下面是一个示例,它读取地址文本文件(每行一个),获取其市议会区,并将其附加到该行。它可以工作——除了输出行的顺序与输入的顺序不同,而且我还没有找到一种方法让它们在同步模式下,在 url 超时时不会无限期卡住。

<!DOCTYPE html>
<html><head><body>
<h1>LAS - Find My District Widget</h1>
<h2>Select a text file (.txt) with a list of addresses - each in a new line. The Widget will return the corresponding districts.</h2>
<input id="input-file" type="file">
<hr><textarea id="output-box" cols="250"></textarea>
<script>
var baseUrl = "https://changedthistoprotectprivacy";
var input = document.getElementById('input-file');
var output = document.getElementById('output-box');

function writeSuccesOutput(geoclientResp) {
var address = geoclientResp.input.replace(/(?:\r\n|\r|\n)/g,"");
var cityCouncil = geoclientResp['results'][0].response.cityCouncilDistrict;
var addressWithCcd = address + ' City Council District ' + cityCouncil + '\n';
output.textContent += addressWithCcd;
}

function writeErrorOutput(error) {
var address = geoclientResp.input.replace(/(?:\r\n|\r|\n)/g,"");
var message = address + ' ERROR ' + error + '\n';
output.textContent += message;
}

function geocode(address) {
var querystring = encodeURI(address);
var url = baseUrl + querystring;
fetch(url).then(function(response) {
response.json().then(writeSuccesOutput);
}).catch(writeErrorOutput);
}

var reader = new FileReader();
reader.onloadend = function (event) {
output.textContent = ''
var addressList = event.target.result.split("\n");
for (var i = 0; i < addressList.length; i++) {
geocode(addressList[i]);
}
}

input.onchange = function() {
if (this.files && this.files[0]) {
reader.readAsBinaryString(this.files[0]);
}
}
</script>
</body>
</html>

最佳答案

您的实际要求是保持结果与输入的顺序相同,以便我们可以确定哪些坐标属于哪个地址。您可以使用 Promise.all() ,它会在给定所有 Promise 解析时进行解析,并以相同的顺序返回结果。

Promise.all()

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

var reader = new FileReader();
reader.onloadend = function (event) {
output.textContent = ''
var addressList = event.target.result.split("\n");
var prmises = addressList.map(address => geocode(address));
Promise.all(promises).then(coordinates => {
// here coordinates[0] is result for addressList[0] and so on

});
}

// Here is a demo
const fakeApi = (address) => {
const randrom = Math.random() * 1000 + 1000;
return new Promise(resolve => {
setTimeout(() => resolve(`${address}_${randrom}`), 10);
});
};

const addresses = ['A', 'B', 'C', 'D', 'E', 'F'];

const promises = addresses.map(address => fakeApi(address));
console.log(addresses);
Promise.all(promises).then(results => {
console.log(results);
});

关于javascript - 真正同步运行多次 fetch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50381326/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com