我在JS中有一些websocket代码。我有这样的消息处理循环:
socket.addEventListener('message', function (event) {
payload = JSON.parse(event.data)
method = payload.method
// Dispatch messages
if (method == 'cmd1') {
handle_cmd1(payload); // trigger event/semaphore here to wait up waiter
}
else if (method == 'cmd2') { ... }
});
在其他地方,我有一个像这样的按钮回调:
$('#my-button').change(function() {
handle_button();
});
async function handle_button() {
send_msg('msg1', 'hi');
// wait for server to reply with cmd1
cmd1_data = await something(); // what?
alert(`cmd1 data: $(cmd1_data)`);
}
这个想法是该按钮发送“ msg1”,服务器应该以“ cmd1”和一些信息进行回复。我想等待该回复,然后再做一些事情。 所以我的问题是如何互锁这些?在C ++中,我将使用信号量。我宁愿不要自旋循环;我可以用来触发然后等待用户定义的事件的Javascript / JQuery中有什么吗?我对JS很陌生,对JS async / await也很陌生。
编辑:我做了一个简单的jsfiddle来显示我想要的。 http://jsfiddle.net/xpvt214o/484700/
答案 0 :(得分:0)
something()应该是一个返回promise()的方法,或者应该是另一个也用async表示的方法。
function something(){
return new Promise(resolve,reject) {
//... call your database
// then
resolve(theResult)
// or
reject(theError)
}
}
大多数情况下,异步和等待实际上只是对诺言的包装。当promise调用解决时,等待返回,当promise调用拒绝时,将引发异常。
您的异步函数可以返回另一个promise;如果它返回另一个值,它将变成具有该值的已解决的承诺。
答案 1 :(得分:0)
现在,我了解了Javascript中的Promise如何工作,下面是一个可以通过调用函数从任何地方唤醒的Promise的工作示例:
wakeup = null;
// returns a promise that will be resolved by calling wakeup()
// (could be a list of these or whatever, this is just a simple demo)
function wakeable() {
return new Promise( (resolve) => {
wakeup = () => { resolve(true); }
});
}
// demo of waiting and getting woken up:
async function handle_event() {
while (true) {
console.log("waiting...")
await wakeable(); // returns to event loop here
console.log("handle event woke up!");
}
}
handle_event(); // start in "background"
wakeup(); // wake it up
setTimeout(_ => { wakeup(); }, 500); // wake it up again after a delay
这里发生的是,当您调用wakeable()
时,它会返回一个承诺。那个诺言是用匿名函数构造的(以resolve
为arg的那个); promise构造函数同步调用该函数,并向其传递promise的resolve方法。在我们的例子中,该函数将wakeup
设置为另一个调用原始resolve
的匿名函数;它是一个闭包,因此即使稍后调用它也可以访问该resolve函数。然后它返回新的承诺。
在此演示中,我们然后await
兑现承诺。将待处理的promise放入队列中,保存当前函数状态,然后返回,就像调用yield
的生成器一样。
一个promise在其resolve函数被调用时便被解析;在这种情况下,调用wakeup()
会调用promise的内部resolve()方法,该方法会在Javascript事件循环的下一个滴答时触发任何.then
方法(使用上述的promise队列)。这里我们使用await
,但是.then(...)
的工作方式相同'
因此没有魔法; I / O和超时承诺的工作方式相同。它们保留了一个私有注册表,用于在I / O事件或超时发生时调用这些函数,并且这些函数调用promise的resolve()来触发.then()
或满足await
。
顺便说一句,与python中的async不同,在Javascript中,当进程退出时将待处理的Promise保持为“打开”状态是完全可以的,实际上,此演示演示了这一点。当没有更多的代码可运行时,它退出。 while循环仍在“等待”这一事实并不能使进程继续运行,因为它实际上只是存储在队列中的某些闭包。事件循环为空,因此流程退出(假设它位于node.js中-在浏览器中,它仅返回到等待事件)。