axios 如果所有迭代都返回空,则执行某些操作,如果其中一个迭代返回某些操作,则执行其他操作

nwlls2ji  于 2023-10-18  发布在  iOS
关注(0)|答案(4)|浏览(154)

我有一个数组的值,我需要通过这些循环运行一个函数的基础上的值,我从一个文本框。
我的代码:

<label for="truck">Truck:</label>
<input type="text" id="truck" name="truck">
<button type="button" id="myButton">Click Me!</button>

const truckBtn = document.getElementById("myButton");
const truckID = document.getElementById("truck");
truckBtn.addEventListener("click", () => {

  let arrs = ["one", "two", "three"];

  for (const arr of arrs) {
     axiosFunction(arr, truckID.value).then(d=> {
      console.log(d.data);
      if (d.data.length > 0) {
         // do something
      } else alert("Not Found");
   });
  }
});

所以d.data如果truckID.value匹配我需要的,则响应是:

[]
[]
[{...}]

这就是它进入if语句的时候。
另一种情况是:
如果truckID.value不匹配我需要的响应是:

[]
[]
[]

我的问题是,当我有else,它去其他即使有匹配。当数组的长度大于0且至少有一次迭代时,有没有办法写一个if语句?如果所有迭代都返回长度为0,则执行else?

gopyfrb3

gopyfrb31#

如果您可以重写axiosFunction背后的API,以获取所有三个arr值并返回一个批处理,那么您就不会进行多次往返,这将是理想的。但是假设你不能这样做,并且你可以等待所有的往返返回(否则你不知道它们是否都返回空的),你可以使用Promise.all()来等待,直到它们都被解析。

<label for="truck">Truck:</label>
<input type="text" id="truck" name="truck">
<button type="button" id="myButton">Click Me!</button>

truckBtn.addEventListener("click", () => {

  let arrs = ["one", "two", "three"];
  Promise.all(arrs.map(arr => axiosFunction(arr, truckID.value)))
    .then(results => {
      console.log(results.map(d => d.data)); // [[], [], [...]]
      const firstValidResult = results.find(d => d.data.length > 0);
      if(firstValidResult) {
         // do something with firstValidResult.data
      } else alert("Not Found");
    });
});

这段代码使用find,假设您只需要一个有效的结果。如果可能有几个,你可以调整它使用filter

bvn4nwqk

bvn4nwqk2#

将回调函数设置为一个pwdc函数,这样就可以使用await。然后,您可以根据任何调用是否返回某些内容来设置一个变量。

truckBtn.addEventListener("click", async() => {
  let arrs = ["one", "two", "three"];
  let found = false;
  for (const arr of arrs) {
    let d = await axiosFunction(arr, truckID.value);
    console.log(d.data);
    if (d.data.length > 0) {
      found = true;
      // do stuff
    }
  }
  if (!found) {
    console.log("Not found!");
  }
});
iovurdzv

iovurdzv3#

这也取决于你打算如何在数组中循环-你想:

  • 只对第一场比赛进行操作,或
  • 对每场比赛进行操作

找到匹配项后,可以使用break扩展您的示例:

const truckBtn = document.getElementById("myButton");
const truckID = document.getElementById("truck");

truckBtn.addEventListener("click", () => {
  let arrs = ["one", "two", "three"];

  for (const arr of arrs) {
     axiosFunction(arr, truckID.value).then(d=> {
      console.log(d.data);
      if (d.data.length > 0) {
         // do something
         break; // don't perform anymore work once we have any match
      } else alert("Not Found");
   });
  }
});

当找到匹配项时,请注意条件中的break-这将阻止对axiosFunction的任何后续调用,这可能是也可能不是您想要的。
下面是处理调用的几种方法,具体取决于您是要等待每个调用,获取第一个匹配结果,还是使用async / awaitArray.map获取所有匹配结果:

const arrs = ["one", "two", "three"];

// execute axiosFunction calls in sequence, like using a for loop
truckBtn.addEventListener("click", async () => {
  const matches = arrs.map(async x => await axiosFunction(x, truckID.value))
        .filter(x => x.data.length > 0);
  const match = matches.find(Boolean); // get the first truthy result

  // do something if match is not null
}

// execute all axiosFunction calls in parallel
truckBtn.addEventListener("click", async () => {
  const promises = arrs.map(x => axiosFunction(x, truckID.value));
  // get all matches
  const matches = await Promise.all(promises)
                    .filter(x => x.data.length > 0);
  const match = matches.find(Boolean); // get the first truthy result

  // do something if match is not null
}

// execute axiosFunction calls in parallel, waiting for the first to resolve
truckBtn.addEventListener("click", async () => {
  const promises = arrs.map(x => axiosFunction(x, truckID.value));
  const firstResolved = await Promise.race(promises);
  const match = firstResolved.data.length > 0 ? firstResolved : null;

  // do something with match
});

// execute axiosFunction calls in parallel, handling if none of them resolve
truckBtn.addEventListener("click", async () => {
  const promises = arrs.map(x => axiosFunction(x, truckID.value));
  let match = null;

  try {
    const firstResolved = await Promise.any(promises);
    match = firstResolved.data.length > 0 ? firstResolved : match;
  } catch (err) {
    // no promise resolved
  }
  
  // do something with match
});
mo49yndu

mo49yndu4#

当您使用axiosFunction发出多个请求时,首先需要使用Promise.allSettled()Promise.all()解析这些promises
然后,您可以使用Array.prototype.some()Array.prototype.every()来检查返回的数据,看起来您需要嵌套其中两个,因为您的结果是一个包含更多数组的数组。
下面是一个模拟axiosFunction的例子。在输入字段中键入foo作为一个结果,或者键入其他内容作为“未找到”:

const searchButton = document.getElementById("searchButton");
const truckInput = document.getElementById("truckInput");

const items = ["one", "two", "three"];

function axiosFunction(array, value) {
  return Promise.resolve({
    data: value === 'foo' ? array.map((_, i) => [{}]) : array.map(_ => []),
  })
}

searchButton.addEventListener("click", async () => {
  const { value } = truckInput;
 
  // Make all requests in parallel:
  const promises = items.map((item) => {
    return axiosFunction(items, value)
  })
  
  // Wait for all of them to resolve:
  const results = await Promise.allSettled(promises);
  
  // Extract the data part from the results:
  const resultsData = results.map(result => result.value.data);
  
  console.log(resultsData);
  
  // Iterate over the data from each request:
  const found = resultsData.some((resultData) => {
    // Itereate over the array items returned by each request:
    return resultData.some((resultItem) => {
      // And check if any of them contains something:
      return resultItem.length > 0;
    });
  })
  
  if (found) {
    alert("Found!");
  } else {
    alert("Not Found...");
  }
});
<label for="truck">Truck:</label>
<input type="text" id="truckInput">
<button type="button" id="searchButton">Search</button>

相关问题