解决外部事件的承诺
Resolve promise on external event
我想在不同函数中发生事件时解决承诺
const trigger = function() {}
const eventHandler = async function() {
while(true) {
await new Promise (resolve => {
}
// Code when the promise fulfills.
}
}
const cleaner = function() {
trigger()
}
cleaner()
下面是一个示例,说明您可以如何使承诺可取消。我们正在使用一个接受承诺的辅助函数 makeCancelable() ,以及 returns 一个不同的承诺和一个取消函数。没有办法只“取消”现有的承诺,尤其是当您无法控制承诺的方式时,但您可以做的是将现有的承诺包装在一个新的承诺中,该承诺的行为与原始承诺一样,但是也准备好根据命令解决。
// 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>
在此代码示例中,“成功!”将每秒打印一次——除非你按下按钮取消当前的承诺。重复按下按钮将延迟“成功!”不会被不确定地打印出来,因为 promise 被取消并提供了值“Canceled!”取消发生的时间。
使用 waitFor method of the EventEmitter2 package (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);
您可以通过重新分配 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
函数。
我想在不同函数中发生事件时解决承诺
const trigger = function() {}
const eventHandler = async function() {
while(true) {
await new Promise (resolve => {
}
// Code when the promise fulfills.
}
}
const cleaner = function() {
trigger()
}
cleaner()
下面是一个示例,说明您可以如何使承诺可取消。我们正在使用一个接受承诺的辅助函数 makeCancelable() ,以及 returns 一个不同的承诺和一个取消函数。没有办法只“取消”现有的承诺,尤其是当您无法控制承诺的方式时,但您可以做的是将现有的承诺包装在一个新的承诺中,该承诺的行为与原始承诺一样,但是也准备好根据命令解决。
// 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>
在此代码示例中,“成功!”将每秒打印一次——除非你按下按钮取消当前的承诺。重复按下按钮将延迟“成功!”不会被不确定地打印出来,因为 promise 被取消并提供了值“Canceled!”取消发生的时间。
使用 waitFor method of the EventEmitter2 package (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);
您可以通过重新分配 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
函数。