【问题标题】:Return value of event triggered function事件触发函数的返回值
【发布时间】:2019-12-13 01:55:21
【问题描述】:

我只是实现了一个在单击按钮后调用的函数。该函数工作正常,但我无法让它返回一个值并将其分配给一个变量。

我想在单击按钮后调用函数play,然后将值(如代码所示)返回给变量,以便将来使用它们。

我已经实现了我需要的所有东西(我正在搞乱网络音频 api)并且它工作正常,test1 变量“嵌入”了osclfo 变量,我能够在函数之外访问它们。

var ac = new AudioContext();

function play(){
     var osc = ac.createOscillator();
     var lfo = ac.createOscillator();
     osc.frequency.value=1000;
     console.log("Clicked!!");
     returnedObject={};
     returnedObject["value1"] = osc;
     returnedObject["value2"] = lfo;
     return returnedObject;
};

var test1= play();
var test= document.getElementById("mybtn").addEventListener("click", play);

test1 变量包含我需要的内容,但 test 变量没有。

如何在事件调用函数的返回对象后将其分配给变量?

如果我使用test.value1,我现在得到的是undefined 错误,这让我认为变量的分配失败。

【问题讨论】:

  • addEventListener 确实 not 返回回调结果,因为它不是同步的。它只是绑定事件,您应该直接在 play 函数中分配值。 developer.mozilla.org/en-US/docs/Web/API/EventTarget/… 按设计返回undefined,并且有意这样做。
  • 你期待什么?在单击按钮之前,不会调用事件处理程序的 play。 javascript 不会阻止。
  • @briosheje 所以我应该创建一个变量,当它被监听器调用时将它传递给播放函数,然后在播放函数内部分配值,对吧?
  • @MattiaSurricchio 不,您应该将值分配给全局 test 变量inside 您的play 回调。
  • @MattiaSurricchio 我建议你使用闭包而不是污染全局命名空间。请参阅下面的代码

标签: javascript function button listener


【解决方案1】:

答案:

您可以这样做,但您必须考虑到该值是undefined,直到单击按钮。

var ac = new AudioContext();

function play(){
     var osc = ac.createOscillator();
     var lfo = ac.createOscillator();
     console.log("Clicked!!");
     returnedObject={};
     returnedObject["value1"] = osc;
     returnedObject["value2"] = lfo;
     return returnedObject;
};

var test;
document.getElementById("mybtn").addEventListener("click", () => (test = play()));
<button id="mybtn">click me</button>

为了使用数据执行功能,您可能需要创建一个中间函数来处理您想要完成的任何工作:

var ac = new AudioContext();

function play(){
     var osc = ac.createOscillator();
     var lfo = ac.createOscillator();
     console.log("Clicked!!");
     returnedObject={};
     returnedObject["value1"] = osc;
     returnedObject["value2"] = lfo;
     return returnedObject;
};

function middle(fn) {
return function() {
let data = fn();

//do something
console.dir(data);
}
}

document.getElementById("mybtn").addEventListener("click", middle(play));
<button id="mybtn">click me</button>

或者,您可以创建一个保存数据的构造函数,从而允许您向构造函数添加方法以供以后操作:

function Player() {
  let proto = {};
  proto.ac = new AudioContext();
  proto.data = [];
  proto.play = function() {
    var osc = proto.ac.createOscillator();
    var lfo = proto.ac.createOscillator();
     proto.data.push({
      value1: osc,
      value2: lfo
    });
 proto.latest = proto.data[proto.data.length-1];
        console.log("Clicked!!", proto.latest);
  };
  

  return proto;
}

const myPlayer = new Player();

document.getElementById("mybtn").addEventListener("click", myPlayer.play);
<button id="mybtn">click me</button>

【讨论】:

  • 这正是我所需要的。我知道如果我不点击按钮,我的价值将是不确定的!非常聪明的解决方案,我没有考虑使用 lambda 表达式然后将值分配给我的变量,真的很聪明!
【解决方案2】:

我会建议你改用闭包。 试试这样的。

 // closure
        function audioControl() {

            var ac = new AudioContext();
            var props = {
                value1: ac.createOscillator(),
                value2: ac.createOscillator()
            };
            // function play
            function play() {
                osc.frequency.value = 1000;
                console.log("Clicked!!");
                props.value1 = "_modified_value";
                props.value2 = "_modified_value";
            }
            return {
                props: props,
                play: play
            }
        };

        var test1 = audioControl();
        var test = document.getElementById("mybtn").addEventListener("click", test1.play);

        // now you can get values anywhere anytime using
        // -- test1.props.value1;

【讨论】:

    【解决方案3】:

    addEventListener 在设计上是为了返回任何东西(感谢@AmitJoki 提及)as you can read in the MDN docs

    相关部分为(摘自this section

    事件监听器只接受一个参数,即Event Object,它会自动传递给监听器,返回值被忽略

    这背后的原因是addEventListener只是为了注册一个事件,而不是处理它的结果。

    如果您想将结果分配给全局变量 test,您应该在您的 play 回调内部执行此操作。

    【讨论】:

    • “意味着返回未定义”,不。它不会 return 任何值是 undefined 的。它的函数体中不会有return undefined
    • @AmitJoki 不确定是否有,但 MDN 在返回部分提到了undefined。事实上,据我所知,它应该返回,我只是想尽可能接近这里所说的:developer.mozilla.org/en-US/docs/Web/API/EventTarget/…。无论如何,我会编辑答案,因为你的观点是有道理的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 2018-03-17
    • 2015-04-01
    • 1970-01-01
    相关资源
    最近更新 更多