提问人:Peppe L-G 提问时间:11/14/2023 更新时间:11/14/2023 访问量:19
提供带有 promise 的同步和异步 API
Provide both a synchronous and asynchronous API with promises
问:
我正在创建一个库,其中库的使用者应该能够在库中完成不同的步骤,并且使用者应该能够决定库何时进入下一步。为了实现这一点,我让消费者将承诺传递给库,然后消费者可以在进入下一步时解决。一个虚拟的例子是这样的:
// A library function.
export async function processName(getNamePromise){
const name = await getNamePromise
console.log(`Hello ${name}!`)
}
现在,使用者可以通过解析 promise 来决定库何时应转到库中的下一步。一个虚拟示例:
import {processName} from './the-lib.js'
const getNamePromise = new Promise(resolve => {
document.getElementById(`inputName`).addEventListener('keyup', function(event){
// This JS code does probably not work as it is, but you get the idea.
if(event.keyCode == "enter"){
resolve(event.target.value)
}
})
})
processName(getNamePromise)
这很好用!但是,有时我想同步使用该库。我希望将已经解决的承诺传递给库会使其同步运行,但库中的每个似乎都将下一步放在事件队列的末尾,因此实际上无论如何都会异步运行:await
processName()
import {processName} from './the-lib.js'
const getNamePromise = Promise.resolve(`Peter`)
processName(getNamePromise)
console.log(`Done processing!`)
使用上面的代码,记录在之前。我需要它反过来。Done processing
Hello Peter!
我真的非常非常想避免在使用已解析的 promise 进行调用时使用,因为我需要在前端框架中执行此操作,该框架会在反应变量更改时自动重新运行计算,并且为了加快速度,我还需要使用方法调用的缓存。在这里能够以同步方式使用该库会容易得多。如果一个已解决的承诺不会导致事件队列中出现新工作,那么这一切都会很好...... -.-await
processName()
await
在库中,一种有效的解决方法是检查承诺是否已解决,并且仅在尚未解决时才使用,如下所示:await
// A library function.
export async function processName(getNamePromise){
const name = getNamePromise.isResolved() ? getNamePromise.getResolvedValue() : await getNamePromise
console.log(`Hello ${name}!`)
}
但是不存在,无论如何它都是一个混乱的解决方案。Promise.isResolved()
Promise.getResolvedValue()
我目前的解决方法是,当代码应该同步运行时,不要将名称包装在 promise 中,并且仅在收到 promise 时在 lib 中使用:await
// A library function.
export async function processName(getNamePromise){
const name = typeof getNamePromise == "string" ? getNamePromise : await getNamePromise
console.log(`Hello ${name}!`)
}
import {processName} from './the-lib.js'
const name = `Peter`
processName(name)
console.log(`Done processing!`)
仍然很乱,但这就是我现在的做法。有谁知道是否存在更好的解决方案来提供一个库,消费者可以在其中将承诺传递给库(告诉库何时进入下一个“步骤”),以及库应该同步运行的特殊情况?
有谁知道为什么解决的承诺会将新作业推送到事件队列?在完成一个已经解决的承诺时,简单地完成当前工作不是更合乎逻辑、更快捷吗?await
await
答: 暂无答案
评论