【问题标题】:JavaScript not a function with promiseJavaScript 不是一个有承诺的函数
【发布时间】:2018-06-14 08:49:06
【问题描述】:

由于我处理的 API 的不寻常性质,我在 JS 中遇到了奇怪的 Promise 相关问题。我有按钮从 API 异步获取数据并处理它们。

按钮代码

$("#hist-testu").on("click",function(){
 bbhistory_object=BBhistory();

 Promise.all([bbhistory_object]).then(function(result_array){
 //do some stuff
 })
})

我对按钮有承诺,因为按钮可能会启动更多子进程,代码必须等待。

BBHistory函数:

function BBhistory(){
 return BBobject = new Promise(function(resolve,reject){

  var fetch_1 = new Promise(function(resolve,reject){
    //do some async stuff
    resolve(some_strings);
   });

  var fetch_2 = new Promise(function(resolve,reject){
    //do some async stuff
    resolve(some_strings);
   });

  Promise.all([fetch_1, fetch_2]).then(function(result_array){
    //do some stuff with results
    BBhistory = result;
    BBtransactions = result;
    BBobject={0:BBhistory,1:BBtransactions};
    resolve(BBobject);
  })

 })
}

如您所见,我获取了 API 调用的 2 个结果,并将它们作为对象返回给主代码/按钮响应,以便我可以在显示阶段使用它。 第一次单击按钮时一切正常。但是在第二次运行时,我继续在按钮的第一行收到 Uncaught Type Error: BBhistory is not a function。我尝试取消定义/清除所有涉及的变量,但无济于事..

编辑: 尽管 cmets 和答案中有很好的解决方案和提示,但真正的原因是 BBhistory 变量在 Promise.all() 中被双重使用。将该 var 更改为其他内容可以解决最初的问题。

【问题讨论】:

  • 我怀疑您没有显示代码的相关部分。你确定你在其他地方没有BBhistory = ,类似于那个可怕的return BBObject =
  • 2个sn-ps是否在同一个文件中?
  • 除了 Denys 上面的评论:1. 在BBhistory 中,将返回的承诺存储在变量中(相对而言)没有意义,2. 更没有意义解析时用新值覆盖该变量,3. 甚至 less 意义使该变量在函数本身之外可见,甚至可能是全局的(您没有显示任何声明 BBobject 的内容)。 4. 在点击处理程序中,当您只处理一个承诺时,没有理由使用Promise.all
  • @DenysSéguret 你是对的!这是一个愚蠢的错误,我在第一个异步中将 BBhistory 用作变量,但假设如果它是不同的类型,它将起作用(duh!)
  • @T.J.Crowder 为什么你认为我不应该将承诺结果存储在变量中?当我尝试删除 BBObject 时,我遇到了解决未定义的错误。而且它不是全球性的 :) 你已经在另一篇文章 AFAIR 中向我指出了这一点:D Point clicker 将在最终解决方案中使用多个承诺。

标签: javascript jquery promise


【解决方案1】:

我认为您可以简化很多。无需使用 resolve 和 reject 回调来创建 Promise 函数。 fetch 函数返回一个 Promise,Promise.all 返回一个 Promise。因此,只需返回该承诺,而不是包装所有内容。

HTML

<button id="MyButton">Press Me</button>

<p>
String 1:
<span id="string1"></span>
</p>
<p>
String 2:
<span id="string2"></span>
</p>

JavaScript

$("#MyButton").click(myClick);

function myClick() {
    BBhistory().then(function(arr) {
        $("#string1").text(arr[0]);    
        $("#string2").text(arr[1]);    

        // Do some other stuff with results
    });
};

function BBhistory() {

  var fetch_1 = Promise.resolve("some_strings 1");   
  var fetch_2 = Promise.resolve("some_strings 2");

  return Promise.all([fetch_1, fetch_2]);  
}

https://jsfiddle.net/5h8ztho3/4/

【讨论】:

  • 虽然这是真的,但它并不能回答问题。如果 OP 得到 "BBhistory is not a function",只需更改 BBhistory 的内容,点击处理程序将无法解决此问题。
  • 正式注明。我已经用完整的功能更新了答案......我认为他正在寻找的东西。
猜你喜欢
  • 1970-01-01
  • 2016-07-22
  • 2022-12-04
  • 1970-01-01
  • 1970-01-01
  • 2014-08-31
  • 2015-12-05
  • 2019-07-09
相关资源
最近更新 更多