我想在下面的get请求之间添加一些超时。我的意思是,流程应该看起来像:timeout, https://example.com/example1, timeout, https://example.com/example2, timeout, https://example.com/example3, timeout
等(或没有首先超时,无论如何)。
以下功能正常工作:
function promiseGetInformationFromMultipleUrls(parts) {
return Promise.all(parts.map(part => {
return request({
'url': `https://example.com/${part}`,
'json': true
}).then(partData => {console.log("Part data was fetched: " + part); return partData.result;})
.catch(err => {console.error("Error during fetching data from part: " + part + ", error code: " + err.statusCode);});
}));
}
其中的部分是 - > example1,example2,example3 ....
我想通过添加计时器来做到这一点:
const timer = ms => new Promise( res => setTimeout(res, ms));
并使用它:
function promiseGetInformationFromMultipleUrls(parts) {
return Promise.all(parts.map(part => {
console.log("wait 1 seconds");
timer(1000).then(_=>console.log("done"));
return request({
'url': `https://example.com/${part}`,
'json': true
}).then(partData => {console.log("Part data was fetched: " + part); return partData.result;})
.catch(err => {console.error("Error during fetching data from part: " + part + ", error code: " + err.statusCode);});
}));
}
但这是错误的流程 - > timeout, timeout, timeout,..., get request1, get request 2, get request 3
。
您可以将其减少为Promise链:
function promiseGetInformationFromMultipleUrls(parts) {
return parts.reduce((chain, part) =>
chain.then((result) =>
timer(1000).then(() =>
request(/*...*/).then(res =>
result.concat(res)
)
)
),
Promise.resolve([])
);
}
不过那很难看,所以你可以使用async / await代替:
async function promiseGetInformationFromMultipleUrls(parts){
const result = [];
for(const part of parts){
await timer(1000);
result.push(await request(/*...*/));
}
return result;
}
以下应该有效:
const Fail = function(reason){this.reason=reason;};
const isFail = x=>(x&&x.constructor)===Fail;
const timedoutPromise = time => promise =>
Promise.race([
promise,
new Promise(
(resolve,reject)=>
setTimeout(
x=>reject("timed out"),
time
)
)
]);
utls = [];//array of urls
in5Seconds = timedoutPromise(5000);
Promise.all(
urls.map(
url=>
in5Seconds(makeRequest(url))
.catch(e=>new Fail([e,url]))//failed, add Fail type object
)
)
.then(
results=>{
const successes = results.filter(x=!isFail(x));
const failed = results.filter(isFail);
const timedOut = failed.filter(([e])=>e==="timed out");
}
)