关于这两个重要来源:NZakas-
承诺链中的归还承诺
和MDN承诺,我想提出以下问题:
每次我们从承诺履行处理程序返回值时,该值如何传递给从同一处理程序返回的新承诺?
例如,
let p1 = new Promise(function(resolve, reject) {
resolve(42);
});
let p2 = new Promise(function(resolve, reject) {
resolve(43);
});
let p3 = p1.then(function(value) {
// first fulfillment handler
console.log(value); // 42
return p2;
});
p3.then(function(value) {
// second fulfillment handler
console.log(value); // 43
});
在这个例子中,p2
是一个承诺。p3
也是来自p1
履行处理程序的承诺。但是p2 !== p3
。取而代之的p2
是神奇地解决43
(如何?),然后将该值传递给p3
的实现处理程序。即使是这里的句子也令人困惑。
您能给我解释一下这到底是怎么回事吗?我对这个概念感到困惑。
假设在then()
回调then()
函数内部抛出结果会导致失败,并从失败中返回,而从回调函数中返回则实现了成功值。
let p2 = p1.then(() => {
throw new Error('lol')
})
// p2 was rejected with Error('lol')
let p3 = p1.then(() => {
return 42
})
// p3 was fulfilled with 42
但是有时候,即使在延续中,我们也不知道我们是否成功。我们需要更多时间。
return checkCache().then(cachedValue => {
if (cachedValue) {
return cachedValue
}
// I want to do some async work here
})
但是,如果我在那里进行异步工作,那么对return
或来说为时已晚throw
,不是吗?
return checkCache().then(cachedValue => {
if (cachedValue) {
return cachedValue
}
fetchData().then(fetchedValue => {
// Doesn’t make sense: it’s too late to return from outer function by now.
// What do we do?
// return fetchedValue
})
})
这就是为什么如果您 无法解决另一个Promise的原因,Promise 不会有用。
这并不意味着在您的示例p2
中将 成为 p3
。它们是单独的Promise对象。然而,通过返回p2
从then()
产生p3
你说
“我想要p3
解析到任何p2
议决,无论成功或失败”。
至于这种情况 如何
发生,则取决于具体实现。在内部,您可以将其then()
视为创建新的Promise。该实现将能够在需要时实现或拒绝它。通常,当您返回时,它将自动实现或拒绝它:
// Warning: this is just an illustration
// and not a real implementation code.
// For example, it completely ignores
// the second then() argument for clarity,
// and completely ignores the Promises/A+
// requirement that continuations are
// run asynchronously.
then(callback) {
// Save these so we can manipulate
// the returned Promise when we are ready
let resolve, reject
// Imagine this._onFulfilled is an internal
// queue of code to run after current Promise resolves.
this._onFulfilled.push(() => {
let result, error, succeeded
try {
// Call your callback!
result = callback(this._result)
succeeded = true
} catch (err) {
error = err
succeeded = false
}
if (succeeded) {
// If your callback returned a value,
// fulfill the returned Promise to it
resolve(result)
} else {
// If your callback threw an error,
// reject the returned Promise with it
reject(error)
}
})
// then() returns a Promise
return new Promise((_resolve, _reject) => {
resolve = _resolve
reject = _reject
})
}
同样,这是非常伪的代码,但显示了如何then()
在Promise实现中实现的背后思想。
如果我们想增加对解决Promise的支持,我们只需要修改代码以callback
在then()
返回Promise时传递一个特殊的分支:
if (succeeded) {
// If your callback returned a value,
// resolve the returned Promise to it...
if (typeof result.then === 'function') {
// ...unless it is a Promise itself,
// in which case we just pass our internal
// resolve and reject to then() of that Promise
result.then(resolve, reject)
} else {
resolve(result)
}
} else {
// If your callback threw an error,
// reject the returned Promise with it
reject(error)
}
})
让我再次澄清,这不是一个实际的Promise实现,并且有很多漏洞和不兼容之处。但是,它应该使您直观地了解Promise库如何实现解析为Promise。在您对这个想法感到满意之后,我建议您看看实际的Promise实现如何处理此问题。
问题内容: 我正在使用promis模块从请求模块返回我的json数据,但是每次运行它时,它都会为我提供此信息。 我无法正常工作,有人知道这个问题吗?这是我的代码: 问题答案: 许诺是充当未来价值的占位符的对象。您的函数返回该Promise对象。通过将处理程序附加到promise,您可以在promise中获得未来的价值: 这是异步代码,因此,仅能通过处理程序来获得承诺的价值。 修改清单: 在返回的p
问题内容: 我有一个像这样的递归函数 我正在使用它 我注意到您好永远不会返回,因为我怀疑我在递归调用上创建了多个promise,但是我不确定如何从中返回。 如何返回每个递归创建的Promise? 编辑: 结果是 问题答案: 递归是一种功能性遗产,因此将其与功能性样式一起使用可产生最佳效果。这意味着编写接受和操作其输入(而不是依赖于外部状态)和返回值(而不是依赖于突变或副作用)的函数。 你的程序,而
问题内容: 无论我的Promise是否成功解决,我都想执行相同的操作。我不想将相同的功能绑定到两个参数。没有像jQuery一样的东西吗?如果没有,我该如何实现? 问题答案: 没有像jQuery一样的东西吗? 如果没有,我该如何实现? 您可以这样实现自己的方法: 或更广泛地讲,将解析信息传递给回调: 两者都确保原始解析得以维持(当回调中没有异常时),并确保等待诺言。
问题内容: 我已经开发JavaScript几年了,我完全不了解关于promise的麻烦。 看来我所做的就是改变: 无论如何我都可以使用像async这样的库,它有类似以下内容: 哪个代码更多,可读性更差。我在这里什么都没得到,也不是突然变得神奇地“平坦”。更不用说必须将事情变成诺言。 那么,这里的诺言有什么大惊小怪的呢? 问题答案: 承诺不是回调。许诺代表 异步操作 的 未来结果 。当然,以您的方式
本文向大家介绍承诺回调和异步/等待,包括了承诺回调和异步/等待的使用技巧和注意事项,需要的朋友参考一下 首先,我们必须了解两个主要概念 同步编程 异步编程 同步编程 它等待每个语句完成执行,然后再转到下一条语句。 如果语句不相互依赖,但是由于它们在队列中,它们仍在等待执行,则此方法可能会减慢应用程序的速度。 异步编程 在移动到下一条语句之前,它不等待当前语句完成执行。例如,调用Web服务并使用Ja
问题内容: 我知道您不能使异步函数同步运行,但是如何向我的promise链添加某种顺序? 一个结果依赖于先前的promise值,当不发生时,我得到一个未定义的错误。这是一个http请求,因此它依赖于外部因素,例如我的连接执行请求的速度等。 我正在按以下方式调用上述方法。但是console.log返回未定义。 终端打印 问题答案: 尝试从第一个然后回调的返回promise