![](/img/trans.png)
[英]Thenable function. Different return type on call or `await` /`then` applied
[英]Make await return thenable, or infinite recursion in awaiting awaitable
尝试提出API,并混入诸如Promise功能:
class Awaitable {
constructor () {
this.promise = Promise.resolve()
}
then (fn) {
// awaited result must be _this_ instance
return this.promise.then(() => fn(this))
}
}
let smth = await (new Awaitable())
console.log(smth)
此代码创建递归。 要点是使smth
成为新创建的可行实例。
then
以null
存根会使等待的结果不完整。
我不知道这是否有可能,似乎存在一些概念上的障碍,我无法全神贯注。
诺言(或任何可能的话)实现自己是没有意义的。 如果已经有了对象,则无需等待。
兑现诺言确实会自动解包ableables ,这将在您自己解决的情况下产生无限递归,并且您可以(不幸地)避免这种情况 。 因此,不要尝试这样做。 完全不履行您的诺言( undefined
)。
class Awaitable {
constructor () {
this.promise = Promise.resolve(undefined); // simplified
}
then(onfulfill, onreject) {
return this.promise.then(onfulfill, onreject);
}
// other methods
}
const smth = new Awaitable();
await smth; // works just fine now
console.log(smth);
import { parse as parseStack } from 'stacktrace-parser' class Awaitable { constructor () { this.promise = Promise.resolve() }, [Symbol.thenable]: false, then(fn) { this.promise.then(() => fn(this)) return this } } let smth = await (new Awaitable()) console.log(smth.then) // function
可以通过解析调用thenable
检测thenable
实例是否被await
调用。 这是基于stacktrace-parser包的解决方案:
import { parse as parseStack } from 'stacktrace-parser' class Awaitable { constructor () { this.promise = Promise.resolve() } } Object.defineProperty(Awaitable.prototype, 'then', { get() { let stack = parseStack((new Error).stack) // naive criteria: if stacktrace is leq 3, that's async recursion, bail out // works in webkit, FF/nodejs needs better heuristic if (stack.length <= 3) return null return (fn) => { this.promise.then(() => { fn(this) }) return this } } }) let smth = await (new Awaitable()) console.log(smth.then) // function
FF / nodejs必须增强启发式才能巩固-这需要某种静态分析向导。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.