嵌套函数中的未定义变量

Posted

技术标签:

【中文标题】嵌套函数中的未定义变量【英文标题】:Undefined variables within nested function 【发布时间】:2018-08-31 15:05:55 【问题描述】:

我有一个返回 ID 的 http post 请求。然后我尝试将该 ID 传递给另一个函数。但是,在下一个函数中,我有一个超时,它将循环该函数以检查状态。 ID 每次在 timeout 函数内都返回 undefined。

第一个函数

这里我有'res',它是另一个函数的结果。我从返回的 json 中获取状态 ID 并将其发送到“getAlbum”。

anotherFunction(res) 
  this.getAlbum(res);

获取相册

如果我立即在此函数内执行控制台日志,它会正确发出正确的 ID。但是,如果我在“checkAblumStatus”函数中执行此操作,则 id 部分未定义。

getAlbum(id)

 var statusID = id.status_id;

  console.log('id = ' + statusID) // returns id

  var statusIDRequest = 'url' + statusID;

  var checkAblumStatus = function (statusIDRequest) 

    console.log('statusIDRequest = ' + statusIDRequest) // returns undefined for the ID part

    this.http.get(statusIDRequest).subscribe(res => 
      if (res.status == "completed") 
        // completed
       else if (res.status == "failed") 
        // failed
       else 
        setTimeout(checkAblumStatus, 1000);
      
    );
  ;

  setTimeout(checkAblumStatus, 1000);

这里的任何帮助将不胜感激:)

【问题讨论】:

What's the meaning of "=>" (an arrow formed from equals & greater than) in javascript?的可能重复 【参考方案1】:

发生这种情况是因为变量的范围。

  var checkAblumStatus = function (statusIDRequest) 

    console.log('statusIDRequest = ' + statusIDRequest) // returns undefined for the ID part

    this.http.get(statusIDRequest).subscribe(res => 
      if (res.status == "completed") 
        // completed
       else if (res.status == "failed") 
        // failed
       else 
        setTimeout(checkAblumStatus, 1000);
      
    );
  ;

在您的函数上下文中,this 引用的是函数本身,而不是您的对象。

您需要像这样使用闭包或粗箭头。

  var checkAblumStatus = (statusIDRequest) => 

您还需要为调用提供一个变量。

setTimeout(checkAblumStatus(variable), 1000);

【讨论】:

感谢@trichetriche 的回复。我试了一下。但是,在类型“对象”上不存在带有“[ts] 属性“状态”的打字稿中的“res.status”行错误。在使用粗箭头。 您输入错误的服务功能。试试这个this.http.get(statusIDRequest).subscribe((res: any) => ,或者重新输入你的服务函数。 太棒了。我现在实际上得到了结果。现在唯一的问题是,当它达到“else”结果时,它不会再循环回去测试该函数。我尝试将您的变量设置为 setTimeOut 并获取“无法调用其类型缺少调用签名的表达式。类型 'void' 没有兼容的调用签名。' setTimeout(() => checkAblumStatus(variable), 1000); 应该可以工作 我害怕同样的事情。【参考方案2】:

您可以按如下方式传递函数的 id

function getAlbum(id)

 var statusID = id.status_id;

  console.log('id = ' + statusID) // returns id

  var statusIDRequest = 'url' + statusID;

  var checkAblumStatus = ((statusIDRequest) => 

    console.log('statusIDRequest = ' + statusIDRequest) // returns undefined for the ID part

    this.http.get(statusIDRequest).subscribe(res => 
      if (res.status == "completed") 
        // completed
       else if (res.status == "failed") 
        // failed
       else 
        setTimeout(checkAblumStatus, 1000);
      
    );
  )(statusIDRequest);

  setTimeout(checkAblumStatus, 1000);

【讨论】:

嗨 Raed,谢谢!我只是试了一下。它导致“错误类型错误:无法读取未定义的属性'http'”。有什么想法吗? 我编辑答案,把函数改成箭头函数【参考方案3】:

您对变量和参数名称感到困惑。

var statusIDRequest = 'url' + statusID;
       ^       ^   // this variable
 var checkAblumStatus = function (statusIDRequest) 
                                     ^     ^ // .. is not the same not this param

像这样改变变量的名字,这样你就不会去掉名字了:

getAlbum(id)

 var statusID = id.status_id;

  console.log('id = ' + statusID) // returns id

  var statusID = 'url' + statusID;

  var checkAblumStatus = function (statusIDRequest) 

    console.log('statusIDRequest = ' + statusIDRequest) // returns the ID part

    this.http.get(statusIDRequest).subscribe(res => 
      if (res.status == "completed") 
        // completed
       else if (res.status == "failed") 
        // failed
       else 
        setTimeout( () => checkAblumStatus (statusIDRequest), 1000);
      
    );
  ;

  setTimeout(() => checkAblumStatus(statusID), 1000);

【讨论】:

以上是关于嵌套函数中的未定义变量的主要内容,如果未能解决你的问题,请参考以下文章

函数的嵌套定义

Python嵌套函数和闭包

函数的嵌套

函数嵌套定义

装饰器之嵌套函数

ZeroC ICE源代码中的那些事 - 嵌套类和局部类