传递或访问作为回调一部分的嵌套函数中的变量

时间:2018-01-25 19:47:00

标签: javascript

您好我有以下代码:

function outer() {

    try {
        ScriptLoader.getScripts('proj4script',proj4Callback);
    }
    catch(e) {console.log(e);}

    function proj4Callback() {
        x = proj4(some geo coord calcs here);
    }

    // I need access to the values stored in x here
}

从代码中可以看出,我使用Scriptloader将proj4脚本加载到我的环境中。不幸的是,这个脚本加载器没有返回值。 scriptloader的一个参数是回调函数 - 该函数不带参数。

我正在尝试访问我在外部函数中调用回调函数的数据。有没有办法让我这样做不涉及在外部函数之外使用全局变量?

编辑:

@Trinot我不确定你继续使用异步调用模式是什么意思,你的意思是这样的:

function main() {
    x = await new Promise(outer());
}

async function outer().then({

    await new Promise(ScriptLoader.getScripts.bind(ScriptLoader, 'proj4script'));
    let x = proj4(/*some geo coord calcs here*/);

    return x;
})

2 个答案:

答案 0 :(得分:2)

您需要拥抱回调的异步特性。因此,您不应尝试以同步方式进行编码。将需要x的代码放在回调中,或者从将x传递给另一个函数的回调中调用函数,等等。无论你做什么,你都需要在回调中继续执行。

现在还有另一种现代方法可以解决这个问题:宣传getScript方法,然后使用async / await

async function outer() {
    await new Promise(ScriptLoader.getScripts.bind(ScriptLoader, 'proj4script'));
    let x = proj4(/*some geo coord calcs here*/);
    console.log(x);
    return x;
}

这会中断函数执行,直到getScripts方法调用回调,在这种情况下是Promise解析器。调用后,执行将在await语句之后执行,并且可以访问您需要计算x的变量。

请注意,调用 outer的代码将在加载脚本之前继续执行。如果您还有依赖于加载脚本的代码,则必须将then方法链接到outer调用,或将该代码也放在async / await中构造

假设您在上述函数中使用return x;,这就是看起来的样子:

async function main() {
    let x = await outer();
    // rest of code that depends on the loaded script
}
main();
// Don't put anything here that needs the loaded script, as it will execute sooner. 

否则:

outer().then(function (x) {
    // rest of code that depends on the loaded script
}
// Don't put anything here that needs the loaded script, as it will execute sooner. 

注意:您可以将await封装在try块中,就像您拥有它一样,但您可以在catch调用上绑定outer()方法调用。

答案 1 :(得分:0)

你应该像这样使用Promises

function outer() {
    var data = new Promise(resolve => {
        ScriptLoader.getScripts('proj4script', function() {
            var x = proj4(12312312312)
            resolve(x)
        })
    })

    data.then(x => {
        //You have the x here
        console.log(x)
    })
}

或使用async/await语法

async function outer() {
    var x = await new Promise(resolve => {
        ScriptLoader.getScripts('proj4script', function() {
            let x = proj4(12312312312)
            resolve(x)
        })
    })

    //You have the x here
    console.log(x)
}

另一个在回调之外声明var x的解决方案

async function outer() {
    var x
    await new Promise(next => {
        ScriptLoader.getScripts('proj4script', function() {
            x = proj4(12312312312)
            next()
        })
    })
    //You have the x with data here
    console.log(x)
}