我很难实现Promises。 (我认为我理解他们,但我经常得到意想不到的结果,所以也许我不会。)
请考虑这段代码。
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范围之后。我的linter声称它是"无法到达&#34 ;;听起来很一致。
在ender调用(//#2)之后,我不想要控制台调用,因为ender毕竟解决了几乎所有ap范围的Promise;退出承诺并退出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范围内Promise的重要性。 "返回"足以离开ender范围,但不是范围。 "解决(' 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的唯一途径包括" return resolve(' ender')&#34 ;;如果我添加"返回"在恩德召唤之后,它会立即让我离开bp范围并且一切都很好。
允许使用不同的函数名称,我期望得到与之前预期相同的结果并获得该结果。好像我的经验教训"可能接近正确答案。
接下来我编写了这段代码(请忽略对j的引用;它们会分散注意力;我认为我需要它们来处理后续问题,但这不是第一次工作,使这篇文章更短!):
function cp(i, j) {
return new Promise(function(resolve, reject) {
console.log('function cp starting i=' + i +
' j=' + j + ' want this');
function ender() {
console.log('function cp ender starting i=' + i +
' j=' + j + ' want this');
i++;
let reps = 3;
if (i < reps) {
cp(i, j)
.then(function(result, error) {
if (error) {
console.log('*** error i=' + i +
' j=' + j + ' msg=' + error.message +
' want this');
return reject(error);
}
console.log('in cp cp('+ i + ', ' + j +
') result=' + result + ' want this');
return resolve(result);
}) // cp(i) callback
console.log('in cp i=' + i + ' j=' + j + '' +
' in ender after reject, resolve, and ' +
'callback don\'t want this'); //#3
} // if (i < reps)
console.log('in cp resolving i=' + i +
' j=' + j + ' want this')
return resolve('done');
} // ender
ender(); return;
console.log('in cp i=' + i + ' j=' + j +
' after ender call and return for cp scope' +
' don\'t want this');
}) // Promise
} // cp
它添加递归并立即跟随ender调用&#34; return&#34 ;;它删除了linter识别出的无法访问的代码;一切都可能顺利。
我得到了
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
这是我期望得到的,除了//#3打印,因为语言没有认识到所有可能性都被&#34;拒绝&#34;或者通过&#34;解决&#34;在回调块内;它继续执行不明智的命令。
这些代码位是我仍然遇到问题的程序的模型。很快,我希望能够模拟出让我感到惊讶的其他行为。
在更一般的层面:Promise的第一次定时器经常无法理解Promises?我们怎样才能有更高的信心,我们才能正确控制执行流程?在这个详细程度解释哪些资源特别有用?我会对这个更普遍的建议表示感谢。
提前致谢...
答案 0 :(得分:2)
这里真正的答案是拒绝和解决 简单回调并标记拒绝/解决Promise。他们没有修改原来的JavaScript工作方式,这是你的假设&#34; 我想要在ender调用后想要控制台调用因为ender(//#2),毕竟,解决了几乎所有ap范围的Promise;退出承诺并退出ap。&#34;
并不奇怪致电reject
或resolve
只是意味着您将履行该承诺。它并不代表你这样做的功能会马上退出。如果您愿意,肯定 - 请使用return
。
你的下一个例子也是如此:
if (i < reps) {
cp(i, j)
.then(...)
console.log(... // you DON'T want this
}
好吧,是的,尽管你不想要它,你肯定会得到它。您创建了一个if
语句,在其中您执行了一些Promise魔术,然后使用console.log
。所以JavaScript并不关心它是否是承诺 - 它只是一个接一个地执行。
如果你仔细阅读Promises,你会发现它们是纯JavaScript,里面有try-catch
,所以如果抛出错误,它们就可以捕获它并调用失败回调(通常提供.catch(function(err){})
)。
再次 - 承诺不要修改JavaScript的工作方式!你所说的一切都是非常合乎逻辑的,应该确实以恰当的方式发生。而且这是因为你希望Promise阻止你的其他代码,这根本不会发生:)