从侦听器函数Javascript返回变量

时间:2014-10-15 01:49:58

标签: javascript return-value

我知道变量是按值传递的,对象是通过引用传递的,但有人可以告诉我如何在成功调用监听器并在函数内生成一些数据后返回值吗?以下是来自Chrome消息传递API的侦听器示例,假设还有另一个脚本返回request.sentVariable:

var something = "";

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
    if (request.greeting == "hello") {
       something = request.sentVariable; ///*******************///
       sendResponse({farewell: "goodbye"});
    }
  });

需要通过内部函数生成的数据更新something变量,而这不是为侦听器分配变量并返回所需数据的工作

var something = chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension" );
    if (request.greeting == "hello") {
      something = request.sentVariable;      ///**************///
      sendResponse({farewell: "goodbye"});
    }
    return something
  });
console.log(something);   ///****************///

所以,是的,我确定这是显而易见的事情,但目前还不确定。

1 个答案:

答案 0 :(得分:2)

这是异步功能的常见问题,在人们掌握它们如何工作之前。在你的第二个代码块中,你

  • something定义为addListener的结果,我相信undefined
  • 输出something(即undefined
  • 然后一段时间后,事件被触发,something被重新定义为request.sentVariable。到这个时候,没有人关心。

您无法从异步函数返回变量。它无法完成。您需要在函数内部使用变量,或者在函数将调用的回调函数中使用。

让我再说一遍,因为它很重要:

  

有人可以告诉我在成功调用监听器并在函数中生成一些数据后如何返回值吗?

没有。无法做到。不可能。决不。不。

你可以做的是:

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension" );
    if (request.greeting == "hello") {
      gotSomething(request.sentVariable);      ///**************///
      sendResponse({farewell: "goodbye"});
    }
  });

function gotSomething(something) {
  console.log(something);
}

编辑:如果您需要来自不同事件处理程序的两个不同的值,请使用promises,或者如果您不想处理promise库,则很容易实现你自己的简单案例:

var data1, data2;
var listener1 = function(request, sender, sendResponse) {
  // ... -> data
  data1 = data;
  handleData();
}
var listener2 = function(request, sender, sendResponse) {
  // ... -> data
  data2 = data;
  handleData();
}
function handleData() {
  if (data1 && data2) {
    // use data1 and data2
    // clear data1 and data2 so we can expect the next pair
    data1 = void 0;
    data2 = void 0;
  }
}
// set listener1 and listener2 as listeners