[在此输入图像说明] [1]我有以下代码
function fnIsOnScreen(img, repeats = 5, desc, wait = 2000) {
let iCounter = 0;
return new Promise((resolve, reject) => {
console.log("Click is running");
var interval = setInterval(() => {
client.screenshot().then((data) => {
let buf = new Buffer(data.value, 'base64');
let img1 = cv.imdecode(buf)
result = img1.matchTemplate(img, 5).minMaxLoc();
if (result.maxVal >= 0.65) {
clearInterval(interval);
console.log("Object found #" + iCounter + " " + desc);
resolve(result);
} else {
console.log("Cant see object yet #" + iCounter);
iCounter++;
if (iCounter === repeats) {
clearInterval(interval);
let err = new Error("Object not found : " + desc);
throw err;
console.log(err);
return Promise.reject(err);
}
}
})
.catch ((err) => {
console.log(err);
})
}, wait);
}).catch ((err) => {
console.log(err);
});
}
为什么我无法清除该间隔?我连续几次调用这个函数。看起来它在下次调用函数后会清除它,但这对我没有多大帮助。
https://ctrlv.cz/shots/2018/01/10/kRmO.png
对不起伙计:)我很忙这里。 if语句有效
答案 0 :(得分:1)
有几件事情跳出来:
catch
client.screenshot()
承诺中的间隔。据推测,您希望在iCounter
else
then
中执行相同的new Promise
检查。return Promise.reject(err);
未创建的承诺;从then
承诺上的client.screenshot()
处理程序返回result
无法解决您创建的新承诺,因为您没有链接。setInterval
在引用的代码中未声明。timeout
重试异步操作。它会在操作和计时器之间创建竞争条件。这是一个解决方案,尝试在屏幕截图失败时重试,而根本不使用计时器。请注意,我已将问题分解为特定部分:可重复使用的function timeout(delay) {
return new Promise(resolve => {
setTimeout(resolve, delay);
});
}
function fnIsOnScreenOnce(img, desc, iCounter) {
return client.screenshot()
.then((data) => {
let buf = new Buffer(data.value, 'base64');
let img1 = cv.imdecode(buf)
let result = img1.matchTemplate(img, 5).minMaxLoc();
if (result.maxVal < 0.65) {
// Fail
const msg = "Can't see object yet";
throw new Error(iCounter === undefined ? msg : msg + " #" + iCounter);
}
// All good
return result;
});
}
function fnIsOnScreen(img, repeats = 5, desc, wait = 2000) {
let iCounter = 0;
const attempt = () => fnIsOnScreenOnce(img, desc, iCounter).catch(err => {
console.log(err.message);
iCounter++;
if (iCounter === repeats) {
// Failed, out of retries
throw new Error("Object not found : " + desc);
}
// Retry after waiting
return timeout(wait).then(attempt);
});
return attempt();
}
函数,尝试屏幕截图一次的函数,以及根据需要重试的函数。
maxVal
实例,部分部分替换为存根;它使用一些随机性来模拟屏幕截图失败或在截止点之上或之下返回const client = {
screenshot() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random () < 0.5) {
const maxVal = Math.random();
console.log("resolving with " + maxVal);
resolve({maxVal});
} else {
console.log("rejecting");
reject(new Error("screenshot failed"));
}
}, 10);
});
}
};
function timeout(delay) {
return new Promise(resolve => {
setTimeout(resolve, delay);
});
}
function fnIsOnScreenOnce(img, desc, iCounter) {
return client.screenshot()
.then((data) => {
/*
let buf = new Buffer(data.value, 'base64');
let img1 = cv.imdecode(buf)
let result = img1.matchTemplate(img, 5).minMaxLoc();
*/
let result = data; // Stand in for the above
if (result.maxVal < 0.65) {
// Fail
const msg = "Can't see object yet";
throw new Error(iCounter === undefined ? msg : msg + " #" + iCounter);
}
// All good
return result;
});
}
function fnIsOnScreen(img, repeats = 5, desc, wait = 2000) {
let iCounter = 0;
const attempt = () => fnIsOnScreenOnce(img, desc, iCounter).catch(err => {
console.log(err.message);
iCounter++;
if (iCounter === repeats) {
// Failed, out of retries
throw new Error("Object not found : " + desc);
}
// Retry after waiting
return timeout(wait).then(attempt);
});
return attempt();
}
fnIsOnScreen("img", 5, "desc", 100)
.then(result => { console.log("result", result); })
.catch(err => { console.error("err", err.message); });
,因此您需要多次运行它以查看所有场景:
.as-console-wrapper {
max-height: 100% !important;
}
{{1}}
答案 1 :(得分:0)
创建array
以保存间隔并逐一清除。intervalArray
获取所有间隔并清除它们。
function fnIsOnScreen(img, repeats = 5, desc, wait = 2000) {
let iCounter = 0;
let intervalArray = [];
return new Promise((resolve, reject) => {
console.log("Click is running");
var interval = setInterval(() => {
client.screenshot().then((data) => {
let buf = new Buffer(data.value, 'base64');
let img1 = cv.imdecode(buf)
result = img1.matchTemplate(img, 5).minMaxLoc();
if (result.maxVal >= 0.65) {
intervalArray.push(interval)
clearintro(intervalArray);
console.log("Object found #" + iCounter + " " + desc);
resolve(result);
} else {
console.log("Cant see object yet #" + iCounter);
iCounter++;
if (iCounter === repeats) {
intervalArray.push(interval)
clearintro(intervalArray)
let err = new Error("Object not found : " + desc);
throw err;
console.log(err);
return Promise.reject(err);
}
}
})
.catch ((err) => {
console.log(err);
})
}, wait);
}).catch ((err) => {
console.log(err);
});
}
function clearintro(intervalArr) {
intervalArr.map(item => {
clearInterval(item);
})
}
答案 2 :(得分:-1)
您无法清除间隔,因为您已在函数内部定义了区间变量使其全局化,然后您将能够在函数的任何位置外部和内部清除它
var interval ="";
function fnIsOnScreen(img, repeats = 5, desc, wait = 2000) {
let iCounter = 0;
return new Promise((resolve, reject) => {
console.log("Click is running");
interval = setInterval(() => {
client.screenshot().then((data) => {
let buf = new Buffer(data.value, 'base64');
let img1 = cv.imdecode(buf)
result = img1.matchTemplate(img, 5).minMaxLoc();
if (result.maxVal >= 0.65) {
clearInterval(interval);
console.log("Object found #" + iCounter + " " + desc);
resolve(result);
} else {
console.log("Cant see object yet #" + iCounter);
iCounter++;
if (iCounter === repeats) {
clearInterval(interval);
let err = new Error("Object not found : " + desc);
throw err;
console.log(err);
return Promise.reject(err);
}
}
})
.catch((err) => {
console.log(err);
})
}, wait);
}).catch((err) => {
console.log(err);
})
}
清除功能之外的间隔
clearInterval(interval);