Javascript 承诺的细节;例子

Javascript 承诺的细节;例子,javascript,node.js,recursion,callback,bluebird,Javascript,Node.js,Recursion,Callback,Bluebird,我努力履行承诺。(我想我理解他们,但我经常得到意想不到的结果,所以也许我不理解。) 请考虑一下这个代码 function ap() { return new Promise(function(resolve, reject) { console.log('function ap starting want this'); function ender() { console.log('function ender starting want this');

我努力履行承诺。(我想我理解他们,但我经常得到意想不到的结果,所以也许我不理解。)

请考虑一下这个代码

function ap() {
  return new Promise(function(resolve, reject) {
    console.log('function ap starting   want this');
    function ender() {
      console.log('function ender starting   want this');
      return resolve('ender');
      console.log('after return in ender   don\'t want this'); //#1
    }
    ender()
    console.log('after function ender and its resolve ' +
      'for Promise   don\'t want this'); //#2
  }) // Promise
} // ap

console.log('---')
ap()
.then(function(result, error) {
  if (error) console.log ('error ' + error.message)
  console.log('function ap result   result=' + result +
    '   want this')
})
考虑到我对承诺的理解,我在很多地方都包含了console.log语句,并指出了是否需要打印它们

我期望:

function ap starting   want this
function ender starting   want this
function ap result   result=ender   want this
我不想在ender(//#1)中最后一次调用console.log,因为它是在一次足以让我脱离ender范围的返回之后进行的。我的林特声称它“遥不可及”;听起来是一致的

我不想在ender调用(/#2)之后再调用控制台调用,因为ender毕竟解决了几乎所有ap范围的承诺;退出承诺并退出ap也就不足为奇了

我得到:

function ap starting   want this
function ender starting   want this
after function ender and its resolve for Promise   don't want this
function ap result   result=ender   want this
问题:这是正确的教训吗?该语言不承认ap范围内承诺的重要性。“返回”足以离开ender范围,但不能离开ap范围。“解决(‘ender’)”足以解决承诺。ender调用后,执行链继续,这就是为什么会打印不需要的语句。程序员必须向Promise发送回调函数,并跳出封闭函数的作用域

假设这是真的,我写了这段代码

function bp() {
  return new Promise(function(resolve, reject) {
    console.log('function bp starting   want this')
    function ender() {
      console.log('function ender starting   want this');
      return resolve('ender');
      console.log('after return in ender   don\'t want this');
    }
    ender(); return;
    console.log('after function ender and its resolve ' +
      'for Promise   don\'t want this');
  }) // Promise
} // bp
它与第一个代码的不同之处在于,我在ender调用之后立即添加了一个返回。通过ender的唯一路径包括“返回解析('ender')”;如果我在ender调用后立即添加“return”,它将使我脱离bp的范围,一切可能都会好起来

考虑到不同的函数名,我预期的结果与我先前预期的相同,并得到了该结果。看来我的“经验教训”可能接近正确答案

接下来,我写了这段代码(请忽略对j的引用;它们会分散我的注意力;我想我需要它们来回答后续问题,但第一次没用,这篇文章就缩短了!):

这就是我期望得到的,除了//#3打印,因为该语言没有意识到回调块中的“拒绝”或“解析”包含了所有可能性;它继续执行不明智地放在那个位置的命令

这些代码位是我一直遇到问题的程序的模型。很快,我希望能够模仿其他让我惊讶的行为

在更一般的层面上:第一次做出承诺的人往往无法理解承诺的内容是什么?我们如何才能有更高的信心来正确控制执行流程?在这种详细程度上,哪些资源特别有助于解释?如果您能在这个更一般的层面上提出建议,我将不胜感激


提前感谢…

这里真正的答案是拒绝和解决是简单的回调并标记拒绝/解决承诺。他们没有修改最初的JavaScript工作方式,这是您的假设“我不希望在ender调用之后再调用控制台,因为ender(/#2)毕竟解决了几乎所有ap范围的承诺;退出承诺并退出ap也就不足为奇了。”

调用
reject
resolve
仅表示您将遵守该承诺。这并不意味着您执行此操作的函数将立即退出。因此当然如果您想这样做,请使用
return

下一个例子也是如此:

if (i < reps) {
    cp(i, j)
    .then(...)

    console.log(... // you DON'T want this
}
if(i
嗯,是的,尽管你不想要它,但你肯定会得到它。你创建了一个
if
语句,在其中你做了一些承诺魔法,然后使用
console.log
。所以JavaScript不在乎它是否承诺——它只是一个接一个地执行事情

如果你读了更多关于承诺的内容,你就会明白它们是纯JavaScript,里面有一个
try-catch
,因此如果抛出错误,它们可以捕获它并调用失败回调(通常随
.catch(函数(err){}
)一起提供)


再一次-承诺不会修改JavaScript的工作方式!而且你所说的一切都是非常合乎逻辑的,确实应该以这种方式发生。这是因为你希望承诺会阻止你的其他代码,而这根本不会发生:)

天哪,真的???试着发布相关的细节,而不是整个故事。为什么你甚至使用
j
?第一次做出承诺的人往往不理解承诺的内容?对于堆栈溢出来说太宽了。一个人可以写一本书或者写一篇很长的关于这个话题的文章。这个网站最适合一个简洁的问题,在几个段落中有一个明确的答案,主要不是基于观点的。此外,请求第三方资源被认为是堆栈溢出的主题外。这个问题需要大幅度地清理或关闭,问题并没有那么广泛。只是需要一点耐心才能通读一遍。我写了两个更长的问题。来吧,伙计们!:)谢谢你的宽容和回答。我很难理解承诺的意外行为。我所有的书都没有。我的web搜索未找到此详细信息。我的熟人圈子里没有JavaScript专家。我同意其他人的看法,在回答特定的语法问题时,这样做效果最好;我不想滥用它。我需要另一个指针,比如当我问异步问题时,有人说“看看蓝鸟!”这个人是对的:承诺更好,尽管我希望我有更多的文档。我想可能会有帮助。这只是又一次兑现承诺。祝你好运返回在Promise回调中。因此
return
适用于它所保持的特定函数。如果您有
函数一(){console.log(1);return;console.log(2);}console.log(3)
,您将得到1和3。回归
function cp starting         i=0   j=0   want this
function cp ender starting   i=0   j=0   want this
function cp starting         i=1   j=0   want this
function cp ender starting   i=1   j=0   want this
function cp starting         i=2   j=0   want this
function cp ender starting   i=2   j=0   want this
in cp   resolving   i=3   j=0      want this
in cp   i=2   j=0   in ender after return, resolve, and callback   don't want this
in cp   resolving   i=2   j=0      want this
in cp   i=1   j=0   in ender after return, resolve, and callback   don't want this
in cp   resolving   i=1   j=0      want this
in cp   cp(2, 0)     result=done   want this
in cp   cp(1, 0)     result=done   want this
function cp result   result=done   want this
if (i < reps) {
    cp(i, j)
    .then(...)

    console.log(... // you DON'T want this
}