嘿,这更像是我认为的头脑风暴帮助,如果它冒犯了规则,那就很抱歉。只是不知道在哪里问这个。
背景故事 我正在使用React,并使用Babel来转换ES6 / 7。我正在尝试做的是让一个组件(另一个类)调用一个函数来通知它需要更改的应用程序状态。我希望此函数调用立即返回,而不是阻塞所有以下逻辑。
目前的想法
1)我知道Promises,但我觉得它会让这个电话过于笨重。考虑到外部发生的操作不会返回任何内容(纯粹),也不会抛出调用类需要注意的错误(优雅地失败)。据我所知,我必须这样做才能调用 dispatch 函数...
OtherClass.dispatch()
.then(() => {})
.catch(console.error)
但这似乎是无缘无故的样板。
2)有async
函数装饰器(?),但我认为那些需要使用await
关键字返回解析才能解析。这仍然听起来像阻止我,或使用承诺then
模式
4)我想到了一个混合,这样调用函数只发出dispatch
函数,然后被调用的函数将执行Promise
。如果我说得对,操作应该似乎跳过承诺并返回,而承诺将异步启动,但我不确定是否是这种情况,或者最佳路线。
function dispatch( ) {
new Promise((resolve, reject) => {
...
}).then(() => {})
.catch(console.error)
}
dispatch();
5)使用队列类型数组和无限轮询循环的旧学校方法。调用dispatch
只是将请求推送到队列的末尾,循环(可能使用requestAnimationFrame()
)轮询数组并按顺序完成它们。我担心这可能会在脆弱的情况下杀死cpu / battery,比如将它移植到React Native,它将在移动设备上运行。
我应该注意速度是关键。 #5有一个很好的方法,因为它保持了有序的变化,但这感觉很奇怪。
答案 0 :(得分:1)
您的Promise
版本可以更加简单:
function dispatch() {
Promise.resolve().then(doTheRealWork);
}
那将是异步的;绝不会拒绝,除非doTheRealWork
拒绝/抛出(并且你已经说过它赢了),所以不需要catch
;它会在预定后尽快调用doTheRealWork
async(在大多数浏览器上,作为当前macrotask完成后的微任务)。
当然,你可以给自己一个更简洁的实用方法:
const later = callback => Promise.resolve().then(callback);
和
function dispatch() {
later(doTheRealWork);
}
示例:
const later = callback => Promise.resolve().then(callback);
function dispatch() {
later(doTheRealWork);
}
function doTheRealWork() {
console.log("Doing the real work");
}
console.log("Calling dispatch");
dispatch();
console.log("Back from dispatch");

答案 1 :(得分:0)
根据评论的建议,我做了一些测试。并且实际上对答案感到惊讶,这就是为什么我分享它,如果有人关心或偶然发现它。
测试设置
我正在使用react,所以我刚刚生成了一个包含1000个简单组件(随机彩色方块)的视图,它们都通过回调来监听更新,这些回调会改变它们的颜色。在processAction()
功能期间。 performance.now()
用于跟踪从进程开始到进程结束的时间戳(已调用所有组件的回调)。按钮会触发dispatchAction()
功能以启动该过程
<强>方法强>
我正在按下按钮,因为它只是调用dispatchAction()
;和processAction()
导致它只是循环遍历数组并随机化它并调用它已注册的回调,因此在此过程中没有更改其中的代码。
1)原始阻止方法
function dispatchAction() {
this.processAction(); //This used to be all in dispatchAction but I moved it for tests
}
产生的表现: 5-7ms 平均值
2)T.J。克劳德的建议
function dispatchAction() {
Promise.resolve().then(() => this.processAction()) //Used the anon-call because I may use parameters
}
结果表现: 80-110ms 平均值(为什么?)
3)Seth White的建议(来自评论)
function dispatchAction() {
return new Promise((resolve, reject) => {
this.processAction()
resolve()
}
}
结果表现: 4-7ms 平均值
所以#3返回一个承诺而没有对then
或catch
做任何事情,实际上工作得非常出色。保留异步,至少将性能报告保持原状。