用Java枚举和排序多个承诺

Sirab33

我无法解决这个令人费解的情况:
-我有10个对象组成的数组,这些对象具有两个属性:IDNumimageURL
-假设实际上只有3个对象imageURL设置属性(位于indexposition的对象[0, 4, 9]),我现在想检索其图像。
-我快速创建了另一个imageURLsArray仅包含这3个URL的数组,并使用.mapURL附加Promise到每个URL来对其进行迭代-如下所示:

// (there’s a bit of THREE.js code in here - but don’t let that throw you off: 
// at issue is the enumeration of Promises, which is the universal Javascript 
// problem I’m trying to figure out)

function getTextures(theImageURLsArray) {
    const loader = new THREE.TextureLoader(); // That's a THREE.js class that  
                                              // let's you load images from remote URL's

    return theImageURLsArray.map((currentURL, index) => {
       console.log("  >Inside '.map', currentURL # ", index, " is: ", currentURL);
  
       return new Promise(function(resolve, reject) {
           console.log(" >>Inside 'new Promise' —> will now call THREE.js's 'loader.load()' function!");
    
           loader.load(currentURL, function(theReturnedLoadedTexture) {
              console.log("\n  >RETURNED from 'loader.load()', index#", index, ", with currentURL = ", currentURL);
              console.log("  >Will now call 'resolve()' with this Texture!");
              resolve(theReturnedLoadedTexture)
           },

           function(err) { 
             reject(err);
           })
       }) 

     }) 
   }  

然后,我执行以下操作以使所有事情发生:

Promise.all(getTextures(imageURLsArray))
   .then(returnedTexturesArray => {
       console.log("Here are the returned textures:");
       console.log(returnedTexturesArray);
    
       theTexturesArray = returnedTexturesArray;

       // Gonna iterate MANUALLY through these babies and see what's what:
       for(z = 0; z < theTexturesArray.length; z++) {
         tempTexture = theTexturesArray[z];   
         console.log("tempTexture # ", z, "'s IMAGE property = ", tempTexture.image.currentSrc);
       }
       // I can now use these Textures to map them onto my 3D Materials...
    })
  .catch(err => console.error(err))

所以,这一切工作得很好-除了,在Promises必然返回它们的创建顺序。
这意味着即使我最初在imageURLsArray订购的产品上调用了它们[0, 4, 9],它们也可能会按[4, 9, 0][9, 0, 4]顺序返回

显然,这会imageURLsArray导致原始图生成的图之间不匹配returnedTexturesArray

鉴于最终需要将图像加载到具有清晰枚举了单元格的简单网格表中,因此无法将图像#4加载到单元格0中。

因此,我想弄清楚的是如何index将返回的图像(或Promises?)一直携带到最后,以便我可以根据需要重新排列结果,使它们与原始图像的顺序匹配。

当我说的时候index,我甚至不一定要表示我正在使用的“主”数组中对象原始 index含义-0, 4, and 9,而是至少要index用于.map操作这些对象的含义-0, 1 and 2.

请注意,目标是要处理多达1000个对象及其对应的图像,因此我试图找到一种可扩展且效率最高的解决方案。

jfriend00

首先,Promise.all()将按照与您传递给的承诺相同的顺序对结果进行排序Promise.all()因此,如果您传递了三个promise Promise.all([p1, p2, p3]),那么无论它们完成的顺序如何,您都将以相同的顺序返回数组。因此,如果这是您所需要的,则可以使用返回的顺序。

其次,可以将同时包含id和index的对象传递给函数,并且在使用图像解析时,可以使用包含图像数据和索引的对象进行解析。这将使您知道索引并将数据正确插入数组中。

但是,我可能会采取不同的方法,并Promise.all()为您做更多的工作,因为您可以传递Promise.all()包含promise或values的数组。因此,如果在数组中没有图像和图像数据的位置将promise传递给整个数组,而在已经有图像数据的地方,则结果可能只是一个数组包含您所有的图像数据。

let arrayOfObjects = [{idNum: id1}, {idNum: id2, imageUrl: url2}, ...];

function fillTextures(array) {
    return Promise.all(array.map(obj => {
        if (obj.imageUrl && !obj.texture) {
             return getTexture(obj.imageUrl).then(texture => {
                 obj.texture = texture;
                 return obj;
             });
        } else {
             return obj;
        }
    }));
}

function getTexture(imageUrl) {
   return new Promise(function(resolve, reject) {
       loader.load(imageUrl, function(texture) {
          resolve(texture);
       },  function(err) { 
         reject(err);
       });
   })     
}

fillTextures(arrayOfObjects).then(resultsArray => {
    // copy of the original array of objects with .texture property
    // filled in for any object that has .imageUrl property
    console.log(resultsArray);
}).catch(err => {
    console.log(err);
});

这样,您就可以处理整个数组,并且实际上仅在需要它的元素上调用异步操作,并让Promise.all()整个数组保持正确的顺序。我发现这比尝试仅处理某些元素并将它们重新插入到原始数组中更为简单。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档