简体   繁体   English

Javascript递归:突破

[英]Javascript Recursion: Breaking out

I'm having difficulty breaking out of this recursive function. 我很难突破这个递归函数。 The script is a background script for a chrome extension and is sending commands to a content script on the page. 该脚本是chrome扩展程序的后台脚本,正在向页面上的内容脚本发送命令。 For each element in jsonArray, the script will need to: 对于jsonArray中的每个元素,脚本将需要:

  1. Query the page and wait for page refresh 查询页面并等待页面刷新
  2. Grab specific headers 抓取特定的标题

Once it has completed the whole array, it should stop. 一旦完成整个阵列,它应该停止。

Here's what I got: 这是我得到的:

function goGetEm(counter, path){

    key = jsonArray[counter];

    console.log("This is round "+counter+" and I am going to "+path);

    if(counter>=jsonArray.length){
        console.log("finishing");
        return;
    }

    if(path=="query"){
        console.log("querying "+jsonArray[counter]);
        message.sendMessage(tabID, {
            "submitquery": {
                "query": jsonArray[counter],
                "searchFieldID": searchFieldID,
                "submitID": submitID
            }
        }, function(response){
            chrome.tabs.onUpdated.addListener(function(tabID , info) {
                if (info.status == "complete") {
                    console.log("query complete");
                    goGetEm(counter, "grab");
                    return;
                }
            });
        });
    }
    else if(path=="grab"){
        console.log("grabbing");
        message.sendMessage(tabID, {
            "grabdata": {
                "targetID": targetID
            }
        }, function(response){
            console.log("grab complete");
            saveData(key, response);
            goGetEm(counter+1, "query");
            return;
        });
    }
    return;
}

goGetEm(0, "query");

The function does successfully submit queries and grab data. 该功能确实可以成功提交查询并获取数据。 But I believe I'm losing track of all the different loops that are being called and not ending them correctly (I thought that's what all my "returns" would do).. 但是我相信我不会跟踪正在调用的所有不同循环,并且无法正确结束它们(我认为这就是我所有的“返回”所要做的)。

Here is the output (well, some of it) 这是输出(嗯,其中一些)

This is round 0 and I am going to query bg.js:58
querying element0 bg.js:66
query complete bg.js:76
This is round 0 and I am going to grab bg.js:58
grabbing bg.js:84
grab complete bg.js:90
This is round 1 and I am going to query bg.js:58
querying element1 bg.js:66
query complete bg.js:76
This is round 0 and I am going to grab bg.js:58
grabbing bg.js:84
query complete bg.js:76
This is round 1 and I am going to grab bg.js:58
grabbing bg.js:84
grab complete bg.js:90
This is round 1 and I am going to query bg.js:58
querying element1 bg.js:66
grab complete bg.js:90
This is round 2 and I am going to query bg.js:58
finishing bg.js:60
Object
 bg.js:48
query complete bg.js:76
This is round 0 and I am going to grab bg.js:58
grabbing bg.js:84
query complete bg.js:76
This is round 1 and I am going to grab bg.js:58
grabbing bg.js:84
query complete bg.js:76
This is round 1 and I am going to grab bg.js:58
grabbing bg.js:84
grab complete bg.js:90
This is round 1 and I am going to query bg.js:58
querying element1 bg.js:66
grab complete bg.js:90
This is round 2 and I am going to query bg.js:58
finishing bg.js:60
Object
 bg.js:48
grab complete bg.js:90
This is round 2 and I am going to query bg.js:58
finishing bg.js:60
Object
 bg.js:48
query complete bg.js:76
This is round 0 and I am going to grab bg.js:58
grabbing bg.js:84
query complete bg.js:76
This is round 1 and I am going to grab bg.js:58
grabbing bg.js:84
query complete bg.js:76
This is round 1 and I am going to grab bg.js:58
grabbing bg.js:84
query complete bg.js:76
This is round 1 and I am going to grab bg.js:58
grabbing bg.js:84
grab complete bg.js:90
This is round 1 and I am going to query bg.js:58
querying element1 bg.js:66
grab complete bg.js:90

and on.... 等等...

I think what's mixing you up is you have async IO going on in there. 我认为让您感到困惑的是您那里正在发生异步IO。 Recursion is about calling the current function and maintaining a call stack, but because you're dealing with callbacks, that doesn't really happen like you think. 递归是关于调用当前函数并维护调用堆栈的,但是由于您正在处理回调,所以这实际上并没有像您想象的那样发生。 This return returns from the listener, not the outer container. return从听者,而不是外部容器返回。

chrome.tabs.onUpdated.addListener(function(tabID , info) {
    if (info.status == "complete") {
        console.log("query complete");
        goGetEm(counter, "grab");
        return;
    }
});

What I'd do is rewrite it so it's iterative. 我要做的就是重写它,这样就可以迭代。 I'd have an object with the callback methods, and the object internally tracks state in the same way you would with a stack. 我将使用回调方法创建一个对象,并且该对象在内部以与堆栈相同的方式跟踪状态。

var worker = {
    queue:[],
    onUpdatedListener: function(tabID , info) {
        ...
    },
    sendMessageComplete: function(response) { ... },
    doWork: function(...) { ... },
    init: function(queue) {
        this.queue = queue;
    }
}

worker.init(jsonArray);
worker.doWork();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM