gpt4 book ai didi

Javascript:如何将附加变量传递给 Promise .catch 函数

转载 作者:行者123 更新时间:2023-11-28 17:36:08 24 4
gpt4 key购买 nike

我已经找到了如何使用 Promise.all 将附加变量传递给 Promise .then 函数。但是如何将这些变量传递给 .catch 函数呢?

我的抽象代码:

// global variable url
var url = [url1, url2, url3];

for (i = 0, i < url.length, i++) {
// run a promise.all to pass some additional variables to the next .then
Promise.all([xhr(url[i]), i]).then(function([response, i]) {
// do something with the response and variable i
alert(url[i] + " responded: " + response);

}).catch(function(e) {
// I need variable i also to be available here!
alert(url[i] + " failed to respond");

});
}

function xhr(url) {
return new Promise(function(resolve, reject) {
// xmlhttprequest with url
// resolves with the response
// or rejects with an error message

});
}

这只是一个非常抽象的代码,用于解释我也需要变量 i 在 .catch 函数中可用。

如何实现这一目标?

编辑:

为了回应答案和我对他们的评论,这里是我在 for 循环中使用 let 的完整代码。我认为现在这是一个非常巧妙的使用 promise 来并行搜索不同的搜索引擎并使用第一个有用的命中。我使用 Promise.any - 一个倒置的 Promise.all - 从一系列 promise 中获取第一个已解决的 promise 。我使用 for 循环来准备 Promise.any 的 promise 。 nzbDonkeySettings 是一个带有我的设置的全局变量:

// modifiy the promise prototype to add function "any"
// from https://stackoverflow.com/questions/39940152/get-first-fulfilled-promise
Promise.prototype.invert = function() {
return new Promise((res, rej) => this.then(rej, res));
};
Promise.any = function(ps) {
return Promise.all(ps.map((p) => p.invert())).invert();
};

// function to search and download the nzb file
function searchNZB(nzbHeader) {

// prepare the promises for all search engines
var getNZB = []; // the promise array
for (let i = 0; i < nzbDonkeySettings.searchengines.length; i++) {
if (nzbDonkeySettings.searchengines[i].active) { // but only for "active" search engines
getNZB[i] = new Promise(function(resolve, reject) {

// first search for the nzb header
var nzbSearchURL = nzbDonkeySettings.searchengines[i].searchURL.replace(/%s/, encodeURI(nzbHeader));
var options = {
"url": nzbSearchURL,
"responseType": "text",
"timeout": 20000
};
xhr(options).then(function(response) {
// if we have a response, check if we have a result
var re = new RegExp(nzbDonkeySettings.searchengines[i].searchPattern, "i");
if (re.test(response)) {
// if we have a result, generate the url for the nzb file
var nzbDownloadURL = nzbDonkeySettings.searchengines[i].downloadURL.replace(/%s/, response.match(re)[nzbDonkeySettings.searchengines[i].searchGroup]);
// and download the nzb file
var options = {
"url": nzbDownloadURL,
"responseType": "text",
"timeout": 120000
};
xhr(options).then(function(response) {
// if we have a response, check if it is a nzb file
if (response.match(/<nzb.*>/i)) {
// if it is a nzb file, resolve with the nzb file
resolve(response);
} else {
// if it is not a nzb file, reject
reject(new Error(nzbDonkeySettings.searchengines[i].name + ": " + "the downloaded file is not a valid nzb file"));
}
}).catch(function(e) {
// if the download failed, reject
reject(new Error(nzbDonkeySettings.searchengines[i].name + ": " + "an error occurred while trying to download the nzb file"));
});
} else {
// if we have no result, reject
reject(new Error(nzbDonkeySettings.searchengines[i].name + ": " + "no nzb file found"));
}
}).catch(function(e) {
// if we have no response, reject
reject(new Error(nzbDonkeySettings.searchengines[i].name + ": " + "an error occurred while searching for the nzb file"));
});

});
}
}

// return a promise
return new Promise(function(resolve, reject) {

// lets "race" the promises and get the result from the first resolved promise
Promise.any(getNZB).then(function(nzbFile) {
// resolve with the nzbFile
resolve(nzbFile);
}).catch(function(e) {
// if we have no results, reject
reject(new Error("no search engine returned any usable result"));
});

});

}

最佳答案

像这样使用let:

for (let i = 0, i < url.length, i++) {

letfor 循环的每次迭代创建一个单独的变量 i,因此即使 for 循环在您的 xhr() 请求运行时继续运行,循环的每次调用仍然可以访问其自己的 i 副本。

<小时/>

此外,根本没有理由在循环内使用Promise.all()。对于循环的每次迭代,您只有一个 xhr() Promise:

// global variable url
var url = [url1, url2, url3];

for (i = 0, i < url.length, i++) {
// run a promise.all to pass some additional variables to the next .then
xhr(url[i]).then(function([response, i]) {
// do something with the response and variable i
alert(url[i] + " responded: " + response);

}).catch(function(e) {
// I need variable i also to be available here!
alert(url[i] + " failed to respond");

});
}

现在,如果您想知道所有 xhr() 调用何时完成,您可以这样做:

// global variable url
var url = [url1, url2, url3];

Promise.all(url.map((u, i) => {
return xhr(u).catch(err => {
console.log(u + " failed to respond");
return null;
});
})).then(results => {
console.log(results);
}).catch(err => {
console.log(err);
});

关于Javascript:如何将附加变量传递给 Promise .catch 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49088912/

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