我基本上只是想验证资源是否可以从执行客户端访问.我无法使用XHR,因为目标资源不允许这样做.
我是JS的新手,我正在使用它(executable here):
var done = false;
var i = 1;
var t = "https://i.stack.imgur.com/Ya15i.jpg";
while(!done && i < 4)
{
console.log("try "+i);
done = chk(t);
sleep(1000);
i = i+1;
if (done)
{
console.log("Reachable!");
break;
}
else
{
console.log("Unreachable.");
}
}
function chk(target)
{
console.log("checking "+target)
fetch(target,{mode: 'no-cors'}).then(r=>{
return true;
})
.catch(e=>{
return false;
});
}
// busy fake sleep
function sleep(s)
{
var now = new Date().getTime();
while(new Date().getTime() < now + s){ /* busy sleep */ }
}
我期待这段代码检查资源,打印结果,然后等待一秒钟.重复此操作直到3次尝试失败或其中一次尝试成功.
相反,执行阻止一段时间,然后立即打印所有console.logs,资源永远不可访问(它是).
我知道fetch操作是异步的,但我想如果我之前声明完成并实现了一个睡眠它应该工作.在最坏的情况下,while循环将使用先前声明的done.
我如何实现所描述的行为?欢迎任何建议.
最佳答案
你的睡眠功能是阻塞的,你真正想要的是一个递归函数,它在检查url n次后延迟y秒等时返回一个promise.
像这样的东西
function chk(target,times,delay) {
return new Promise((res,rej) => { // return a promise
(function rec(i) { // recursive IIFE
fetch(target,{mode: 'no-cors'}).then((r) => { // fetch the resourse
res(r); // resolve promise if success
}).catch( err => {
if (times === 0) // if number of tries reached
return rej(err); // don't try again
setTimeout(() => rec(--times),delay ) // otherwise,wait and try
}); // again until no more tries
})(times);
});
}
要像这样使用
var t = "https://i.stack.imgur.com/Ya15i.jpg";
chk(t,3,1000).then( image => {
console.log('success')
}).catch( err => {
console.log('error')
});
请注意,这不会在404或500上失败,任何响应都是成功的请求.