【问题标题】:Use variable of one function in another (Three.js) Javascript在另一个(Three.js)Javascript中使用一个函数的变量
【发布时间】:2020-04-20 11:44:35
【问题描述】:

我使用 three.js 加载了一个 obj 文件 我尝试获取其顶点“X”位置并将其保存在 init() 函数中的 objloader 函数内的“pos”中。 我想在另一个函数中使用变量的值,比如 displayposition() 当我尝试时

var pos;

function init() {
    var objLoader = new THREE.OBJLoader();
    objLoader.load('objectfile.obj', function(object) {
        scene.add(object);
        pos = scene.children[5].children[0].geometry.attributes.position.getX(0);
        console.log(pos); //This displays the vertex position value
    });
}

function displaypos() {
    console.log(pos); //It doesn't display the vertex position value
}

如何使其成为全局变量并使 'pos' 的变量值在整个程序中可用..

【问题讨论】:

  • 当你将pos分配到回调中时,你不必重新声明。您应该将var pos = scene... 替换为pos = scene...。如果你声明它,回调中的pos 将是一个与全局pos 完全不同的变量,只是名称相同。
  • 我删除了 var re-declaration 仍然没有显示值..
  • 您是否检查过回调是否在displaypos 方法之前被调用?
  • 是的,我首先调用了 init();然后继续 displaypos();
  • 好的,但您是否确认也调用了回调?您传递给objLoader.load 方法的那个。另外,我建议改进缩进。

标签: javascript variables three.js scope global-variables


【解决方案1】:

OBJLoader.load 是一个异步函数,用于下载和解析 OBJ 文件。这可能根本不需要时间,也可能需要几秒钟。

你说你打电话给init,紧接着是displaypos。这些函数调用是连续的,所以displaypos 将在init 退出后立即调用

这里的操作顺序是:

  1. 创建全局变量pos
  2. 定义init函数
  3. 定义displaypos函数
  4. 致电init
    1. objloader 定义为THREE.OBJLoader
    2. 定义objLoader.load的回调
    3. 调用objLoader.load
    4. init 退出 因为对 objloader.load 的调用是连续调用的
  5. 致电displaypos
    1. undefined 打印到控制台

几秒钟后……

  1. objloader.load 的回调被调用
    1. object 添加到scene
    2. 设置pos的值
    3. console.log 将正确的值打印到控制台

因此,您的 displaypos 调用没有打印该值,因为没有要打印的值...。

您可以将自己的回调添加到init 以使其按预期工作,或者您可以重新编写代码以使用Promise + async/await

回调版本

var pos;

function init(callback) {
    var objLoader = new THREE.OBJLoader();
    objLoader.load('objectfile.obj', function(object) {
        scene.add(object);
        pos = scene.children[5].children[0].geometry.attributes.position.getX(0);
        console.log(pos); //This displays the vertex position value
        callback(); // The real exit point
    });
}

function displaypos() {
    console.log(pos);
}

init(function(){
    displaypos(); // will now display the correct value
});

// alternately: init(displaypos);

承诺 + 异步/等待

var pos;

async function init() {
    return new Promise(function(resolve){

        var objLoader = new THREE.OBJLoader();
        objLoader.load('objectfile.obj', function(object) {
            scene.add(object);
            pos = scene.children[5].children[0].geometry.attributes.position.getX(0);
            console.log(pos); //This displays the vertex position value
            resolve(); // the real exit point
        });

    });
}

function displaypos() {
    console.log(pos);
}

(async function(){
    await init();
    displaypos(); // will display the correct value
})();

【讨论】:

  • 非常感谢您的工作..很好的答案和很好的解释..但是有没有一种方法可以在不使用回调或承诺函数的情况下将 pos 用作全局变量..如果我想在 loader 函数之后获取 console.log(pos) 但仍在 init() 函数中我仍然未定义。有没有办法在其他函数的相同函数中获取该 pos..就像我想要一个全局声明..跨度>
  • @PopupDev 否。您希望以同步方式使用变量(全局的),但您在异步上下文中分配它的值。我建议您阅读一下 JavaScript 中同步与异步操作的工作原理。 Here's a good starting point,您可以在网上找到更多信息。
猜你喜欢
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
  • 2019-03-30
相关资源
最近更新 更多