Javascript: 使用 foreach 循环嵌套获取..?

Javascript: nested fetch with foreach loop..?

这是我的问题:我需要向我的服务器发出一些提取 POST 请求。服务器保存一个名称列表。每个名称都对应一个我需要浏览的元素列表,以便从所有列表中找到特定元素。 我必须使用此结构,无法更改它。

我的方法是编写一个提取请求,以获取所有这些名称(我需要浏览的列表),然后循环遍历每个名​​称并提取以从服务器获取相应的列表。获得这些列表后,我可以遍历元素,直到找到正确的元素。

这对我来说不是一件容易的事,因为我是 javascript 的新手。

我是这样实现的:

function browse(){
      fetch(TARGET_IP, {
            method: "POST",
            headers: {
                "Content-type": "application/json",
                "X-Auth-Token": AUTH_TOKEN
            },
            body: JSON.stringify({
                "id": messageId++,
                "jsonrpc": "2.0",
                "method": "Browse",
                "params": {
                    "mode": "children"
                }
            })
        })
            .then(response => response.json())
            .then((data) =>  {

                data.results = Object.assign(Array.prototype, data.result);

                data.results.forEach(element => {
                    if (element.datatype == "datablock") {

                        datablocks.push(element.name)
                    }
                })

                return datablocks;

            })
            .then((datablocks) => {
                datablocks.forEach(element => {
                    
                    browseDatablocks(element)
                })
            })

            .catch(e => console.error(e))
}


function browseDatablocks(dbname) {

    fetch(TARGET_IP, {
        method: "POST",
        headers: {
            "Content-type": "application/json",
            "X-Auth-Token": AUTH_TOKEN
        },
        body: JSON.stringify({
            "id": messageId++,
            "jsonrpc": "2.0",
            "method": "Browse",
            "params": {
                "var": "\"" + dbname + "\"",
                "mode": "children"
            }
        })
    })
        .then(response => response.json())
        .then((data) => {

            data.results = Object.assign(Array.prototype, data.result);

            data.results.forEach(element => {
                    
                if (element.name == "P_Index")
                {
                    console.warn(dbname);
                    // This is the element I need and would save it
                }
            })

        })

        .catch(e => console.error(e))
}


现在这种方法会发生各种奇怪的事情。

控制台输出的元素不是我搜索的元素,这是我在服务器端检查的错误。

有些请求甚至没有得到处理。

我认为这些问题的发生是因为我同时发送了太多请求(浏览数据块中的嵌套请求)。 如何处理一个请求然后再处理下一个请求?或者还有其他实现方式吗?

谢谢。

看来你需要的是 Promise.all.

如果我理解正确的话:

首先return获取结果在function browseDatablocks(dbname)

...
function browseDatablocks(dbname) {

  return fetch(TARGET_IP, {
  ....

和return的值,在最后则

.then((data) => {
  data.results = Object.assign(Array.prototype, data.result);

  const filtered = data.results.filter((element) => element.name == "P_Index");

  return filtered;
});

然后在function browse(),最后是:

.then((datablocks) => {
  const results = datablocks.map(element => browseDatablocks(element));

  return Promise.all(results);
})
.then((listOfResults) => {
  // Some magic here
})

// 编辑或按顺序执行:

function browseDatablocks(dbname),最后是:

进行处理,return 一个 bool 而不是 filtered 例如 true = 全部完成,false 获取下一个。类似于:

.then((data) => {
  data.results = Object.assign(Array.prototype, data.result);

  const found = data.results.find(element => element.name == "P_Index");
  if (found) {
    // Some handling
    return true;
  }
  return false;
})

然后在function browse(),最后

.then(async (datablocks) => {
  let i = 0;
  while(i < datablocks.length) {
    const handled = await browseDatablocks(datablocks[i]);

    if (handled === true) {
      break;
    }

    i += 1;
  }
});