【问题标题】:How to pass an additional argument to the callback function in the Three.js loader.parse methodThree.js loader.parse 方法中如何向回调函数传递附加参数
【发布时间】:2022-02-05 20:34:48
【问题描述】:

three.js中Loader对象的Parse方法允许你设置一个回调函数,当解析过程完成时调用。 这个回调被称为传递给它一个唯一的参数,它是被解析的对象。

我的问题是我需要将另一个参数传递给回调。 这是因为我在循环中使用 parse 方法,并且我想为每个人创建许多具有特定变量值的回调。

如果我在循环中设置此值但在回调之外设置回调时不可避免地执行,显然该值始终是循环中设置的最后一个。

这是代码:

for(var foldcont_index in foldcont) {

    var foldit= foldcont[foldcont_index];

    if(foldit.isDirectory()) { loadBFiles(fold+'/'+foldit.name); }

    if(foldit.isFile()) {

      var buigltf= fs.readFileSync(fold+'/'+foldit.name, 'utf8');
      loader.parse(
          buigltf,
          undefined,
          function(o) {
             var oname= // !!! before issue with foldit.name
             objectstank['xxx_'+oname]= o;
             loadpoint= loadpoint+loadpercentage;
             loadbar.set(loadpoint);
             if(loadpoint>= 100) { document.getElementById("load-bar").style.display= 'none'; },
          undefined
          }
        );

    }

}

谁能帮我找到解决办法?

【问题讨论】:

    标签: javascript three.js


    【解决方案1】:

    阅读closures in Javascript

    与 C/C++ 之类的语言不同,在 JavaScript 中“关闭变量”是微不足道的,因此您在 JavaScript 中的回调永远不需要额外的参数,因为您始终可以使用闭包“关闭”回调中需要访问的任何变量

    你的情况

    for(var foldcont_index in foldcont) {
    
        var foldit= foldcont[foldcont_index];
    
        if(foldit.isDirectory()) { loadBFiles(fold+'/'+foldit.name); }
    
        if(foldit.isFile()) {
    
          var buigltf= fs.readFileSync(fold+'/'+foldit.name, 'utf8');
          loader.parse(
              buigltf,
              undefined,
              function(oname) {
                  return function(o) {
                      var oname= // !!! before issue with foldit.name
                      objectstank['xxx_'+oname]= o;
                      loadpoint= loadpoint+loadpercentage;
                      loadbar.set(loadpoint);
                      if(loadpoint>= 100) { document.getElementById("load- bar").style.display= 'none'; }
                  };
              }(foldit.name),
              undefined
          );
    
        }
    }
    

    可能会奏效。 (我可以阅读你的代码)。这不是我在 Three.js 中知道的 Loader 对象。有很多 XXXLoader 对象。不知道你用的是哪一个。

    这种模式

    function(var1, var2, var3) {
       return function() {
          // do something with var1, var2, var2
       };
    }(value1, value2, value2);
    

    是关闭值的常见模式。该代码是一个函数,它返回一个在var1var2var3 上“关闭”的函数。

    因此您可以将返回的函数传递给回调。长手示例

    function makeCallback(var1, var2, var3) {
       return function() {
         console.log(var1, var2, var3);
       };
    }
    
    const fn = makeCallback('Hello', 'World', '!');
    setTimeout(fn, 1000);

    内联版本

    for (let i = 1; i <= 4; ++i) {
      setTimeout(function(var1) {
         return function() {
            console.log(var1);
         };
      }(i), i * 500);
    }

    【讨论】:

      【解决方案2】:

      以下代码可以作为一个有用的示例,因为它被设计为尽可能不言自明。回调函数将“最初不可见”的模型添加到场景中,并将它们添加到列表中。类中的其他方法(未显示)负责动态决定各个模型何时应该可见以及它们应该放置在场景中的什么位置。

      import { GLTFLoader } from 'https://cdn.skypack.dev/three@0.133.1/examples/jsm/loaders/GLTFLoader.js'
      
      export class transitVehicleSystem {
      
        constructor(scene, dParamWithUnits, numWedges) {
      
          this.scene = scene
          this.unallocatedTransitVehicleModels = []
      
          function prepareACallbackFunctionForLoader(myScene, myList) {
            return function( {scene} ) {
              const object = scene.children[0]
              object.visible = false
              for (let i=0; i<dParamWithUnits['numTransitVehicleModels'].value; i++) {
                const tempModel = object.clone()
                myScene.add(tempModel)
                myList.push(tempModel)
              }
            } 
          }
          const addTransitVehicles = prepareACallbackFunctionForLoader(this.scene, this.unallocatedTransitVehicleModels)
      
          const loader = new GLTFLoader()
          loader.load('models/TransitCar.glb',
            // pass in the callback function that was created within a closure
            addTransitVehicles,
            // called when loading is in progresses
            function ( xhr ) {
              console.log( ( xhr.loaded / xhr.total * 100 ) + '% transit car loaded' );
            },
            // called when loading has errors
            function ( error ) {
              console.log( 'An error happened', error );
            }
          )
        
          console.log(this.unallocatedTransitVehicleModels)
        
        }
      *
      *
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-09
        • 2013-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-20
        相关资源
        最近更新 更多