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
}