我基本上只是想验证资源是否可以从执行客户端访问。我无法使用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
操作是异步的,但我想如果我之前声明done
并实现睡眠它应该工作。在最坏的情况下,while循环将使用先前声明的done
。
如何实现所描述的行为?欢迎任何建议。
答案 0 :(得分:2)
你的chk函数返回undefined,你从promise回调中返回true / false,而不是从容器函数返回。
你应该在catch回调中使用递归和超时。 它将是这样的:
var i = 0;
var done = false;
var t = "https://i.stack.imgur.com/Ya15i.jpg";
(function chk(target){
console.log("checking "+target)
fetch(target, {mode: 'no-cors'}).then(r=>{
done = true;
console.log("Reachable!");
})
.catch(e=>{
console.log("Unreachable.");
if(i<4){
setTimeout(function(){
chk(target)
},1000)
}
});
})(t)
答案 1 :(得分:2)
您无法在回调中返回。当你这样做时,它是返回的回调,而不是父函数。事实上,函数const numberOfTries =3;
currentTry = 1;
var t = "https://i.stack.imgur.com/Ya15i.jpg";
chk(t);
function tryCheck(resource, currentTry) {
chk(resource).done(function(){
console.log("Reachable!");
}).catch(function(e) {
console.log("Unreachable.");
if (currentTry >= numberOfTries) return;
sleep(1000);
tryCheck(resource, currentTry + 1);
});
}
function chk(resource) {
console.log("checking "+target);
return fetch(target, {mode: 'no-cors'});
}
永远不会返回任何内容。
你想要做的是返回fetch返回的承诺。并试图取三次。
试试这个:
shell_exec("/usr/bin/ffmpeg -i video.mkv -r 20 -f image2pipe -vcodec ppm - | convert -delay 5 - output.gif");
答案 2 :(得分:2)
主要问题是你试图从回调中返回。这是没有意义的。
但fetch
是基于Promise的请求,您可以使用Promise来模拟延迟
这样的事情可以解决问题
// promise based delay
const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout))
// check if target can be fetched
const check = target => fetch(target, {...})
.then(response => response.ok)
const ping = (target, times = 3, timeout = 1000) => check(target)
.then(found => {
if(!found && times) { // still can check
// wait then ping one more time
return delay(timeout).then(() => ping(target, times - 1, timeout))
}
return found
})
ping('https://i.stack.imgur.com/Ya15i.jpg')
.then(found => {
console.log(found ? 'Reachable': 'Unreachable')
})
答案 3 :(得分:2)
你的sleep
函数是阻塞的,你真正想要的是一个递归函数,在检查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上失败,任何回复都是成功的请求。
答案 4 :(得分:1)
试试这个,希望它有效
var myHeaders = new Headers();
myHeaders.append('Content-Type', 'image/jpeg');
var myInit = { method: 'GET',
headers: myHeaders,
mode: 'no-cors',
cache: 'default' };
var myRequest = new Request('https://i.stack.imgur.com/Ya15i.jpg');
fetch(myRequest,myInit).then(function(response) {
...
});