clearInterval()不起作用

时间:2018-01-10 13:11:29

标签: javascript node.js

[在此输入图像说明] [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语句有效

3 个答案:

答案 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);