【发布时间】:2016-04-04 03:28:10
【问题描述】:
我很难实现 Promise。 (我认为我理解它们,但我经常得到意想不到的结果,所以也许我没有。)
请考虑一下这段代码。
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')
})
鉴于我对 Promise 的理解,我在很多地方都包含了 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 声称它“无法访问”;听起来很一致。
我不希望在 ender 调用 (//#2) 之后进行控制台调用,因为 ender 毕竟解决了几乎所有 ap 范围的 Promise;退出承诺并退出应用程序也就不足为奇了。
我明白了:
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
问题:这是正确的教训吗?该语言无法识别 Promise 在 ap 范围内的显着性。 “返回”足以离开 ender 范围,但不是 ap 范围。 "resolve('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')”;如果我在 ender 调用之后立即添加“return”,它会让我脱离 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 调用之后立即使用“return”;它删除了 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 打印,因为语言不承认回调块中的“拒绝”或“解决”涵盖了所有可能性;它继续执行不明智地放在那个位置的命令。
这些代码位是我仍然遇到问题的程序的模型。很快,我希望能够模拟其他令我惊讶的行为。
在更一般的层面上:第一次使用 Promise 的人经常无法理解 Promise 的哪些方面?我们如何才能更有信心正确控制执行流程?有哪些资源对解释这种详细程度特别有用?对于这个更笼统的层面的任何建议,我将不胜感激。
提前致谢...
【问题讨论】:
-
天啊,认真的???尝试发布相关细节兄弟,而不是整个故事。
-
你为什么还要使用
j? -
诸如 第一次使用 Promises 的人经常无法理解 Promises 的哪些问题? 对于 Stack Overflow 来说太宽泛了。人们可以就该主题写一本书或很长的文章。这个网站最适合处理一个简洁的问题,在几个段落中给出明确的答案,而不是主要基于意见。此外,对于 Stack Overflow,要求 3rd 方资源被认为是题外话。这个问题需要大量清理或关闭。
-
问题不是那么广泛。它只需要一点耐心才能通篇阅读。我已经写了两次更长的问题。拜托了伙计们! :)
标签: javascript node.js recursion callback bluebird