首页 > 解决方案 > Javascipt 中的 Promise 不会执行循环

问题描述

我在 Javascript 中有这段代码

if(!this.top3){
    const promises = this.images.map((el, index) => {
      return this.getData(el.title, index);
    });

    return Promise.all(promises)
    .then(() => {
      this.getUnknown();
      this.$emit("onTaskFinished");
      //this.showResults = true
    })
    .catch((err) => {
      console.error(err);
    });

This.images是一个数组,其中包含图像的名称,title并且data为空。

现在我需要更改函数,因为this.images它将成为一个包含一组图像的数组。每个组都是一个数组,每个组都包含 中的图像data和图像的名称title

所以我以这种方式更改了功能:

var j=0;
 for(j=0; j<this.images.length; j++){
      this.imgIndex = j;
       const promises = this.images[j].title.map((el, index) => {
            return this.getData(el, index);
       })

       return Promise.all(promises)
       .catch((err) => {
          console.error(err);
        });
       
        this.getUnknown();
        this.$emit("onTaskFinished");
  }

这样它就不起作用了,因为for循环只执行了 1 次。

我认为问题Promises在于如果我删除它,程序将永远留在循环中。我是新手,Javascript所以我知道我在做一些错误。

编辑

j++抱歉, for 循环里面当然有一个。

我会给你更多的信息。正如我所说,在旧代码中,this.images.title有图像的标题。

对于每张图片,this.getData()我调用一个 API 到后端给他标题并获取图片。然后我把它放进去this.image[i].data

async getData(img_name, i) {
      await this.$store.dispatch("fetchUserProfile");
      return this.axios
        .get(
          process.env.VUE_APP_ROOT_API + `/getResults/${encodeURIComponent(img_name)}?experiment=${this.experiment}`,
          {
            withCredentials: true,
            responseType: "blob",
            headers: {
              "Content-type": "image/jpeg",
              Authorization: "Bearer " + this.$store.state.userProfile,
            },
          }
        )
        .then((res) => {
          console.log("res: ", res);
          if (res.status == 400) {
            this.$router.push("/login");
            alert("SESSION EXPIRED. PLEASE LOG-IN AGAIN.");
            throw Error("TOKEN EXPIRED");
          } else {
              if(!this.top3){
                  let blob = new Blob([res.data], {
                    type: res.headers["content-type"],
                  });
                  this.images[i].data = URL.createObjectURL(blob);
              }
        })
        .catch((err) => {
          console.error(err);
        });
    }

显然我也改变this.getData()了,以便将响应放在正确的位置,所以我替换this.images[i].data = URL.createObjectURL(blob);this.images[this.imgIndex].data.push(URL.createObjectURL(blob))

它有效,但正如我所说,仅适用于第一个元素,然后它会阻塞。

标签: javascriptvue.js

解决方案


您不需要在循环中使用 return 。在第一次迭代后使用 return 停止循环。

for(var j=0; j<this.images.length; j){

      this.imgIndex = j;
       const promises = this.images[j].title.map((el, index) => {
            return this.getData(el, index);
       })

       await Promise.all(promises)
       .catch((err) => {
          console.error(err);
        });
       
        this.getUnknown();
        this.$emit("onTaskFinished");
        j++;
  }

推荐阅读