我正在写一些与浏览器插件(FF中的附件,IE中的ActiveX)交互的JavaScript。某些调用是异步的,并在完成时触发事件。在某些情况下,我需要将呼叫链接在一起,但需要在启动第二个呼叫之前等待第一个呼叫完成。例如:在JavaScript中同步基于事件的插件调用
连接设备的呼叫需要先检查设备是否已连接,然后断开连接。因此,电话是:
pluginObject.disconnectDevice(deviceKey);
pluginObject.connectDevice(deviceKey, backingInfo);
只是称他们为直像这样因为一个连接启动之前断开是实际完成会失败,并且插件不能处理这个问题。
我已经有听众设置,我可以这样做:
function handleConnectionChange(connectionState, /* ... */, doReconnect) {
if (connectionState === state.disconnected && doReconnect) {
pluginObject.connectDevice(deviceKey, backingInfo);
}
}
但我真的喜欢一个更通用的方法 - 一个是可重复使用的即使有一组不同的链接事件。。在这个特殊的例子中这很简单,但即使这样也有点sl。。我已经为连接事件处理程序添加了重新连接信息逻辑,并且在完成此操作后,我可以轻松地看到有条件的链接失控。
有没有解决这种工作流的库?我看着jQuery的延期东西,它有我想要的链接,但它似乎不适合回调。 Sproutcore的StateCharts看起来很有趣,但似乎又没有能力重做已经异步的流程。
更新:解决方案 感谢来自古斯塔沃一些指点,我已经与捆绑的插件调用,使他们利用jQuery的递延对象的方法:
var connectDevice = function(deviceKey, backingInfo) {
var deferred = $.Deferred();
var connectHandler = function(event) {
// unregister connectHandler
if (event.connectionState === ERROR) {
showAlert("Error connecting device", event.message);
deferred.reject();
} else {
showAlert("Device connected", event.message);
deferred.resolve();
}
};
// register connectHandler
pluginObject.connectDevice(deviceKey, backingInfo);
return deferred.promise();
};
如果我做了类似的包装用于断开,我现在可以链中的方法调用(或不依赖于流量):
if (forceDisconnect) {
disconnectDevice(deviceKey).done(connectDevice(deviceKey, backingType));
} else {
connectDevice(deviceKey, backingType);
}
我还可以启动一个链与connectDevice,或添加其他功能到forceDisco nnect flow等
你如何设置该监听器?它只是'pluginObject.handleConnectionChange = function(){}?' – 2011-06-15 23:03:46
是的,或IE中的attachEvent – Jeff 2011-06-15 23:42:50
然后我的答案应该做的工作! – 2011-06-15 23:52:45