解决外部事件的承诺



当事件发生在不同的函数中时,我想解决一个promise

const trigger = function() {}
const eventHandler = async function() {
while(true) {
await new Promise (resolve => {

}
// Code when the promise fulfills.
}
}
const cleaner = function() {
trigger()
}
cleaner()

通过重新分配trigger:,您可以非常容易地做到这一点

let trigger = () => {}
const eventHandler = async function() {
while(true) {
await new Promise (resolve => {
trigger = resolve
//    ^^^^^^^^^^^^^^^^^
}
// Code when the promise fulfills.
}
}
const cleaner = function() {
trigger() // calls resolve to fulfill the currently waited-for promise
}
eventHandler() // start waiting
cleaner()

但是,请注意,这通常被认为是一种糟糕的做法,您应该启动任何导致外部事件的程序,尤其是在new Promise执行器回调的内部安装事件侦听器,在那里您可以轻松访问resolve函数。

下面是一个如何取消承诺的示例。我们使用的是一个助手函数makeCancelable((,它接受一个promise,并返回一个不同的promise和一个cancel函数。没有办法仅仅";取消";一个现有的承诺,尤其是当你无法控制如何做出承诺时,但你可以做的是将现有的承诺包装在一个新的承诺中,这个承诺的行为与原来的一样,但也可以根据命令进行解决。

// Helper function that just waits for a timeout
const wait = ms => new Promise(resolve => setTimeout(resolve, ms))
function makeCancelable(promise) {
let resolveWrappedPromise
return {
promise: new Promise((resolve, reject) => {
resolveWrappedPromise = resolve
promise.then(resolve, reject)
}),
cancel: value => resolveWrappedPromise(value),
}
}
cancelPromise = () => {} // function used by onClick event
async function eventHandler() {
while (true) {
const { promise, cancel } = makeCancelable(wait(1000).then(() => 'Success!'))
cancelPromise = cancel
console.log(await promise)
}
}
eventHandler()
<button onclick="cancelPromise('Canceled!')">Cancel!</button>

在这个代码示例中;成功"将每秒打印一次-除非您按下按钮取消当前承诺。重复按下按钮将延迟";成功"由于承诺被取消并提供了价值";已取消"当取消发生时。

使用EventEmitter2包的waitFor方法(Live demo(。

import EventEmitter2 from "eventemitter2";
const emitter = new EventEmitter2();
(async () => {
const data = await emitter.waitFor("test");
console.log("emitted", data);
})();
setTimeout(() => emitter.emit("test", 1, 2, 3), 1000); 

最新更新