Javascript 带回调错误的promise catch中的ininfinite循环

Javascript 带回调错误的promise catch中的ininfinite循环,javascript,node.js,promise,bluebird,Javascript,Node.js,Promise,Bluebird,我很确信我误解了承诺的作用,但很多阅读都未能解决我的问题 我已经有了调用另一个模块的现有代码,该模块刚刚被更改为使用承诺。使用旧版本时如下所示: function(params, cb) { ..... asyncFunc(p1, (err, res) => { if (!err) ..... cb(null,'msg'); else cb(err); }; }; 将此更改为: function(params, cb)

我很确信我误解了承诺的作用,但很多阅读都未能解决我的问题

我已经有了调用另一个模块的现有代码,该模块刚刚被更改为使用承诺。使用旧版本时如下所示:

function(params, cb) {
  .....
  asyncFunc(p1, (err, res) => {
    if (!err)
       .....
       cb(null,'msg');
    else
       cb(err);
  };
};
将此更改为:

function(params, cb) {
  .....
asyncFuncwithPromise(p1).then(res = > {
    ...  // X
    return cb(null,'msg');
}).catch(err => {
    cb(err);
});

如果第X行的代码抛出异常,这将进入catch()的无限循环->then()。从catch中删除回调,一切正常。有人能解释一下吗

除非
cb()
正在调用
asyncFuncWithPromise()
,否则无法确定如何在此处创建无限循环

我喜欢将承诺回调链看作两条平行轨道。要继续沿着成功(
then()
)轨迹,请使用
return
关键字。要继续沿着故障(
catch()
)轨迹,请使用
throw
关键字。链的轨迹可以随时切换,但回调只会线性执行;也就是说,链中前面定义的回调不能在后面定义的回调之后执行。链条总是向前推,不能进入循环

Promise.resolve()
  .then(()=>{ // 1S
    if (Math.floor(Math.random() * 2))
      return "success"; // continue down "success" (then) track
    else
      throw "fail"; // continue down "failure" (catch) track
  })
  .then(r=>{ // 2S
    return "all good: " + r;
  })
  .catch(e=>{ // 2F
    // use 'return' to recover, continue down "success" track
    return "recovered from error: " + e;
  })
  .then(r=>{ // 3S
    console.log(r); // always executed
  })
  .catch(e=> { //3F
    console.error(e); // never executed
  });
在本例中,始终会执行带有
console.log()
的链中的最终成功链接(3S),因为
catch()
链接(2F)使用
return
将链返回成功轨道。当然,如果每个链接使用
throw
关键字,则多个链接都可以遵循故障轨迹

使用
Promise
构造函数创建新承诺时,成功和失败跟踪最初对应于解析器中提供的
resolve
reject
函数。因此,这两者(功能上)没有区别:

function getPromise(...) {
  return new Promise((resolve, reject)=>{
    /* do something... */
    if (condition) {
      resolve(result);
    } else {
      reject(error);
    }
  });
}
这是:

function getPromise(...) {
  return Promise.resolve().then(()=>{
    /* do something... */
    if (condition)
      return result;
    else
      throw error;
  });
}

它们之间的区别微妙地与承诺链中的链接如何遵从运行时事件框架有关。这可能因实现而异,但通常
then()
catch()
回调延迟到执行帧的下一个后续帧。

不确定如何在此处创建无限循环,除非
cb()
调用
asyncFuncWithPromise()

我喜欢将承诺回调链看作两条平行轨道。要继续沿着成功(
then()
)轨迹,请使用
return
关键字。要继续沿着故障(
catch()
)轨迹,请使用
throw
关键字。链的轨迹可以随时切换,但回调只会线性执行;也就是说,链中前面定义的回调不能在后面定义的回调之后执行。链条总是向前推,不能进入循环

Promise.resolve()
  .then(()=>{ // 1S
    if (Math.floor(Math.random() * 2))
      return "success"; // continue down "success" (then) track
    else
      throw "fail"; // continue down "failure" (catch) track
  })
  .then(r=>{ // 2S
    return "all good: " + r;
  })
  .catch(e=>{ // 2F
    // use 'return' to recover, continue down "success" track
    return "recovered from error: " + e;
  })
  .then(r=>{ // 3S
    console.log(r); // always executed
  })
  .catch(e=> { //3F
    console.error(e); // never executed
  });
在本例中,始终会执行带有
console.log()
的链中的最终成功链接(3S),因为
catch()
链接(2F)使用
return
将链返回成功轨道。当然,如果每个链接使用
throw
关键字,则多个链接都可以遵循故障轨迹

使用
Promise
构造函数创建新承诺时,成功和失败跟踪最初对应于解析器中提供的
resolve
reject
函数。因此,这两者(功能上)没有区别:

function getPromise(...) {
  return new Promise((resolve, reject)=>{
    /* do something... */
    if (condition) {
      resolve(result);
    } else {
      reject(error);
    }
  });
}
这是:

function getPromise(...) {
  return Promise.resolve().then(()=>{
    /* do something... */
    if (condition)
      return result;
    else
      throw error;
  });
}


它们之间的区别微妙地与承诺链中的链接如何遵从运行时事件框架有关。这在不同的实现中可能有所不同,但通常
then()
catch()
回调会延迟到执行帧的下一个后续帧。

我从未经历过这种情况,但编写了类似的代码。与您的
asyncFuncwithPromise
cb
有关。您的函数是如何使用的,以及如何定义
asyncFuncwithPromise
?需要查看CB函数。它在做你期望的事情吗?它返回什么和/或做什么?谢谢,我将深入研究CB函数(它不是我的),我只是想检查我正在做的基本工作是否被误导。你发布的伪代码中没有错误。我们必须看到真实的代码(包括传入回调中发生的情况),以便通知无限循环的来源。目前的问题可能无法回答。现在您正在使用承诺,通过返回承诺使您的功能“可实现”。现在从函数中清除
cb
,这是不需要的。我从未经历过这种情况,但编写了类似的代码。与您的
asyncFuncwithPromise
cb
有关。您的函数是如何使用的,以及如何定义
asyncFuncwithPromise
?需要查看CB函数。它在做你期望的事情吗?它返回什么和/或做什么?谢谢,我将深入研究CB函数(它不是我的),我只是想检查我正在做的基本工作是否被误导。你发布的伪代码中没有错误。我们必须看到真实的代码(包括传入回调中发生的情况),以便通知无限循环的来源。目前的问题可能无法回答。现在您正在使用承诺,通过返回承诺使您的功能“可实现”。现在从函数中清除
cb
——这是不需要的。关于承诺的某些方面的教程不错,但我不确定这是如何回答OP的问题的。@jfriend00嘿,是的,我知道这可能对问题没有帮助。但是从他所展示的,没有办法知道发生了什么。它进入循环循环的唯一方法是,如果他的
cb()
正在调用
asyncFuncWithPromise()
。我试图澄清承诺机制,希望它可能会引发“啊哈”的时刻。我想我可以看出你在试图帮助,但我们真的希望OP澄清他们的问题,让大家都清楚,而不是试图猜测什么可能会有帮助。事实上,这两个例子之间存在差异。前者将同步执行,后者将同步执行