javascript - 当将参数传递给回调函数时与回调的调用者发生冲突时该怎么办

标签 javascript parameters callback id3

我正在使用 ID3 读取器脚本从音频文件中检索数据。基本用法是:

ID3.loadTags(file,function()
{
  var attr = ID3.getAllTags(file).attribute;
});

其中匿名函数是回调函数。这只是为了提供上下文,但是,我根本不确定我遇到的问题是否特定于该特定脚本。

通常,在回调函数中,您可以提取所需的信息,然后使用 DOM 将任何元素的innerHTML 属性设置为等于您提取的信息。

有时,您会提取一堆信息并将所有信息连接到一个长字符串中,而我会尝试将其进一步划分,以便我的调用函数会更干净一些。我想做的是这样的:

function callingFunction()
{
  var file = "whatever.mp3";
  var info = getInfo(file);
}

function calledFunction(file)
{
  var info = {data: 0};

  ID3.loadTags(file, function(passedVar)
  {
    var dataobj = ID3.getAllTags(file);
    passedVar.data = dataobj.title+etc+dataobj.album+....(it can get long);
  }(info));

  return info;
}

创建带有属性的对象是因为它是 JS 中模拟通过引用传递的唯一方法之一 - 将对象传递到回调函数中,将适当的数据分配给对象中的属性,然后在结束时CalledFunction,返回对象给callingFunction。

但它不起作用。现在,在上面的代码中,如果我说 PassedVar.data = "teststring"而不是从 dataobj 为其分配数据,那就可以了,因此将对象传递到回调函数中可以正常工作。但如果该对象是从 ID3 函数返回的数据对象中分配数据的,则不起作用。它返回未定义,而且 Chrome 的 JS 调试器表示 ID3 函数返回的对象为 null。当我这样做时,这进一步得到证实:

function calledFunction(file)
{
  var info = {data: 0};

  ID3.loadTags(file, function(passedVar)
  {
    alert(ID3.getAllTags(file).(any attribute));
  }(info));

  return info;
}

并且根本没有出现任何警报框。但是,如果删除上面代码中传递给回调函数的参数,并保持其他所有内容相同,则警报框会像预期的那样出现。

所以,总而言之,当我将参数传递给回调函数时,由于某种原因,调用回调函数的对象的另一个函数停止正常工作。

将参数传递到回调函数中是否可能与 ID3.loadTags 函数传递到回调函数中的任何内容发生某种冲突或覆盖,这就是 getAllTags 函数失败的原因?因为由于某种原因,当参数传递到回调函数时, getAllTags 函数不再获取正常运行所需的所有信息?这是我能想到的唯一解释。

如果是这种情况,有办法解决吗?如果这不是正在发生的事情,那么到底发生了什么?

我已经想出了一个解决方案,但我觉得它很糟糕。我基本上创建了从回调函数调用的第三个函数(它本身不接收参数),它将 getAllTags 方法返回的对象作为参数,从该对象中提取数据,并将其分配给其他函数可以使用的全局变量使用权。所以,这个:

var globalVar;

function calledFunction(file)
{
  //var info = {data: 0};

  ID3.loadTags(file, function()
  {
    thirdFunction(ID3.getAllTags(file));
  });

  //return info;
}

function thirdFunction(dataobj)
{
  globalVar = dataobj.title+etc;
}

但我不太喜欢这个解决方案,我觉得它违背了我最初追求的划分精神。

如果有任何帮助,我将不胜感激。

最佳答案

这不起作用的原因:

function calledFunction(file)
{
  var info = {data: 0};

  ID3.loadTags(file, function(passedVar)
  {
    var dataobj = ID3.getAllTags(file);
    passedVar.data = dataobj.title+etc+dataobj.album+....(it can get long);
  }  (info));
  // ^^^^^^ --- calls the function immediately

  return info;
}

...是您调用匿名函数并将该调用的结果(未定义)传递到ID3.loadTags 。您根本不再向其中传递函数。

但根本问题是,您在 loadTags 调用其回调并将数据放入对象之前尝试使用数据对象。

我建议,由于它的输出依赖于异步操作,而不是依赖于函数返回值,因此您可以将 usedFunction 更改为采用回调函数。它应该是这样的:

function callingFunction() {
  getInfo('whatever.mp3', function(info) { // pass a callback function
    // info.data is here now
  });
}

function getInfo(file, cb) { // accept a callback function as the 2nd param
  ID3.loadTags(file, function() {
    var tags = ID3.getAllTags(file);
    // once your async operation is done, call cb and pass back the return value
    cb({
      data: tags.title+etc+tags.album+....(it can get long);
    });
  });
}

这种方法避免了您试图通过使用可以通过引用传递的对象来解决的问题,并且它确保您只有在异步操作 (ID3.getAllTags) 完成后才能继续。

关于javascript - 当将参数传递给回调函数时与回调的调用者发生冲突时该怎么办,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17081005/

相关文章:

javascript将div滚动到 View 中并具有平滑的滚动效果?

javascript - Bootstrap-Date 选择器日期字段未保存到 mysql 数据库

c++ - 将 C++ 函数转换为 Delphi : what to do with void* parameter?

javascript - 如何处理异步函数和集合?

javascript - 如何检查php网站是否完全加载了JS

javascript - 如何从 AngularJS 中的对象数组创建一个类似于对象的空对象?

javascript - 类型错误 : Highcharts[h] is not a function

parameters - move_node.jstree - 查找/理解操作结果参数

php - Laravel: 'on clause' 中的未知列 $parameter

JavaScript:异步事件回调的线程安全? (我需要 'volatile' 还是什么?)