skip to Main Content

I am working on a game and I have a spot in the code where I load all the resources in parallel. Currently it looks something like this:

let [
    grassTexture,
    stoneTexture,
    waterTexture,
    skyTexture,
    sandTexture,
    woodTexture,
    carpetTexture,
    paperTexture,
    steelTexture
] = await Promise.all([
    loadGrassTexture(),
    loadStoneTexture(),
    loadWaterTexture(),
    loadSkyTexture(),
    loadSandTexture(),
    loadWoodTexture(),
    loadCarpetTexture(),
    loadPaperTexture(),
    loadSteelTexture()
])

but that doesn’t strike me as particularly well-designed since it’s easy to mess up the order and it would be better if the result was on the same line with the respective function call. Another option I see is this:

let grassTexture = loadGrassTexture()
let stoneTexture = loadStoneTexture()
let waterTexture = loadWaterTexture()
let skyTexture = loadSkyTexture()
let sandTexture = loadSandTexture()
let woodTexture = loadWoodTexture()
let carpetTexture = loadCarpetTexture()
let paperTexture = loadPaperTexture()
let steelTexture = loadSteelTexture()

await grassTexture
await stoneTexture
await waterTexture
await skyTexture
await sandTexture
await woodTexture
await carpetTexture
await paperTexture
await steelTexture

but that’s not much better. Is there some idiomatic way to do this?

2

Answers


  1. Instead of using separate variables for each resource, put them in an object keyed by the resource names.

    Then you can use Promise.all() followed by a loop to fill in the values.

    const textures = {
        grass: loadGrassTexture(),
        stone: loadStoneTexture(),
        // ...
    };
    
    const results = await Promise.all(Object.values(textures));
    Object.keys(textures).forEach((key, i) => textures[key] = results[i]);
    
    Login or Signup to reply.
  2. You could refactor this to a parametrized function:

    
    //if you can refactor you code to a parameterized load texture function 
    
    async function loadTexture(textureName) {
      //your new code here
    }
    
    const textureNames = ['grass', 'stone', 'water', 'sky', 'sand', 'wood', 'carpet', 'paper', 'steel'];
    
    const texturePromises = textureNames.map(async (name) => [name, await loadTexture(name)]);
    const textureEntries = await Promise.all(texturePromises);
    //now we have a mapping of texture type -> texture
    const textureObject = Object.fromEntries(textureEntries);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search