关联数组未在服务器发送事件环境中填满

Associative array not filling up in server-sent-event environement

我想我走错了路:

我有一个事件源,可以为我提供有关底层系统操作的更新。该页面旨在在 jquery 支持的树表中显示所述事件。我完美地接收了这些事件,但我意识到有一种情况我没有处理,即事件到达但缺少父事件的情况。在这种情况下,我需要从数据库中获取丢失的根以及该根节点的所有可能丢失的子节点。这也很好用。

//init fct
//...
eventSource.addEventListener("new_node", onEventSourceNewNodeEvent);
//...

function onEventSourceNewNodeEvent(event) {
    let data = event.data;
    if (!data)
        return;

    let rows = $(data).filter("tr");
    rows.each(function (index, row) {
        let parentEventId = row.getAttribute("data-tt-parent-id");
        let parentNode = _table.treetable("node", parentEventId);

        // if headless state is not fully
        // resolved yet keep adding new rows to array
        if (headlessRows[parentEventId]) {
            headlessRows[parentEventId].push(row);
            return;
        } else if (parentEventId && !parentNode) { // headless state found
            if (!headlessRows[parentEventId])
                headlessRows[parentEventId] = [];

            headlessRows[parentEventId].push(row);
            fetchMissingNodes(parentEventId);
            return;
        }

        insertNode(row, parentNode);
    });
}

function fetchMissingNodes(parentEventId) {
    let url = _table.data("url") + parentEventId;

    $.get(url, function (data, textStatus, request) {
        if (!data)
            return;

        let rows = $(data).filter("tr");

        //insert root and children into table
        _table.treetable("loadBranch", null, rows);

        let parentNode = _table.treetable("node", parentEventId);
        let lastLoadedRow = $(rows.last());

        let headlessRowsArray = headlessRows[parentEventId];
        while (headlessRowsArray && headlessRowsArray.length > 0) {
            let row = headlessRowsArray.shift();
            let rowId = row.getAttribute("data-tt-id");
            if (rowId <= lastLoadedRow) // already loaded event from previous fetch
                continue;

            insertNode(row, parentNode);

            let pendingUpdatesArray = pendingUpdates[rowId];
            // shouldn't be more than one but who know future versions
            while (pendingUpdatesArray && pendingUpdatesArray.length > 0) {
                let updateEvent = headlessRowsArray.shift();
                updateNode(updateEvent)
            }
            delete pendingUpdates[rowId]; // <- something better here?
        }
        delete headlessRows[parentEventId]; // <- something better here too?

    });
}

问题出在 if (headlessRows[parentEventId]) 行附近。 当我 运行 一步一步(在之前放置调试器指令)时,一切正常,无头数组已创建并正确填充。 但是一旦我让它 运行 全速运行,一切都会崩溃。 我打印的日志似乎表明该阵列的行为方式与我预期的不同。如果我用 console.log 打印数组,它显示如下:

(2957754) [empty × 2957754]
    length : 2957754
    __proto__ : Array(0)

它似乎缺少任何实际数据。而当我一步一步执行时,它显示如下:

(2957748) [empty × 2957747, Array(1)]
    2957747:[tr.node.UNDETERMINED]
    length:2957748
    __proto__:Array(0)

我遗漏了一些东西,但它仍然在躲避我。

你的代码是async的,你做http请求但是把他当作同步代码。 试试这个修复

//init fct
//...
eventSource.addEventListener("new_node", onEventSourceNewNodeEvent);
//...

async function onEventSourceNewNodeEvent(event) {
    let data = event.data;
    if (!data)
        return;

    let rows = $(data).filter("tr");
    rows.each(function (index, row) {
        let parentEventId = row.getAttribute("data-tt-parent-id");
        let parentNode = _table.treetable("node", parentEventId);

        // if headless state is not fully
        // resolved yet keep adding new rows to array
        if (headlessRows[parentEventId]) {
            headlessRows[parentEventId].push(row);
            return;
        } else if (parentEventId && !parentNode) { // headless state found
            if (!headlessRows[parentEventId])
                headlessRows[parentEventId] = [];

            headlessRows[parentEventId].push(row);
            await fetchMissingNodes(parentEventId);
            return;
        }

        insertNode(row, parentNode);
    });
}

function fetchMissingNodes(parentEventId) {
    return new Promise((resolve,reject) =>{
       let url = _table.data("url") + parentEventId;

      $.get(url, function (data, textStatus, request) {
          if (!data){
              resolve()
              return;
          }
              

          let rows = $(data).filter("tr");

          //insert root and children into table
          _table.treetable("loadBranch", null, rows);

          let parentNode = _table.treetable("node", parentEventId);
          let lastLoadedRow = $(rows.last());

          let headlessRowsArray = headlessRows[parentEventId];
          while (headlessRowsArray && headlessRowsArray.length > 0) {
              let row = headlessRowsArray.shift();
              let rowId = row.getAttribute("data-tt-id");
              if (rowId <= lastLoadedRow) // already loaded event from previous fetch
                  continue;

              insertNode(row, parentNode);

              let pendingUpdatesArray = pendingUpdates[rowId];
              // shouldn't be more than one but who know future versions
              while (pendingUpdatesArray && pendingUpdatesArray.length > 0) {
                  let updateEvent = headlessRowsArray.shift();
                  updateNode(updateEvent)
              }
              delete pendingUpdates[rowId]; // <- something better here?
          }
          delete headlessRows[parentEventId]; // <- something better here too?
           resolve()
      });
    })
 
}