我目前正在开发一款主要用于自我教育目的的应用程序,因为我还没有完全习惯于js,我可以为我的问题使用一些帮助:
在我的应用程序中,我使用的是javascript库(jqMobi),用于DOM操作,页面转换,ajax调用等,我还使用phonegap访问设备功能,例如地理定位。
当我启动我的应用程序时,我想获取设备的地理位置,向我的服务器发送ajax(jsonp)请求(包括设备的地理位置),该请求返回我将用于构建的json对象数组列表。
在我获得地理位置之前,我需要等待加载电话空白。在使用jqMobi进行ajax调用并处理响应之前,我需要等待它加载。
所以我基本上要听事件
document.addEventListener("DOMContentLoaded",execute_this,false); //jqMobi is now ready
document.addEventListener("deviceready", execure_sth, false); //Phonegap is now ready
如果这两个事件都被触发而不是之前,我该如何执行一个函数?
如果我使用jQuery,我会使用它的$ .Deferred对象及其When ... Then Function但由于我无权访问这些,我正在寻找替代方案。
提前感谢您的帮助!
答案 0 :(得分:19)
乍一看,这样的事情肯定会奏效:
var executed_this = false, executed_sth = false;
function execute_this() {
executed_this = true;
combined_execution();
}
function execute_sth() {
executed_sth = true;
combined_execution();
}
function combined_execution() {
if (executed_this && executed_sth) {
// magic!
}
}
但是不可扩展(如果你想要第三个事件等待怎么办?)。计数器可以工作:
var wait_on = 2;
function execute_this() {
combined_execution();
}
function execute_sth() {
combined_execution();
}
function combined_execution() {
wait_on--;
if (wait_on === 0) {
// magic!
}
}
更具可扩展性,但假设事件只触发一次。无论哪种方式,这些都是能够控制你所要求的流量控制类型的主要因素,而其他一切(在大多数情况下)都是这两者的更高层次的抽象。
答案 1 :(得分:2)
试试这个,
document.addEventListener("DOMContentLoaded",execute_this,false);
function execute_this(){
document.addEventListener("deviceready", execure_sth, false);
}
function execute_sth(){
//your code here
}
答案 2 :(得分:0)
您可以做出在事件触发时解决的承诺,并等待它们都准备就绪。
var dcl = new Promise(function(resolve) {
document.addEventListener("DOMContentLoaded",resolve,false);
})
var deviceready = new Promise(function(resolve) {
document.addEventListener("deviceready", resolve, false);
})
Promise.all([dcl, deviceready]).then(function() {
//both are ready
});
答案 3 :(得分:0)
将这里的一些答案合并到waitForEvents(eventTarget, eventNames);
用法:
waitForEvents(window, 'DOMContentLoaded,deviceready').then(function() {
// do stuff
});
来源:
/**
* Wait for multiple DOM events to fire
* @param {object} eventTarget - element to listen for events on (default document)
* @param {Array<string>|string} eventNames - array or csv string of event names
* @returns {Promise<Array>} resolves with array of event objects
*/
function waitForEvents(eventTarget, eventNames) {
eventTarget = eventTarget || document;
eventNames = (!Array.isArray(eventNames)) ? String(eventNames).split(',') : eventNames;
// clean event names
eventNames = eventNames.map(function(item) {
return String(item).trim();
})
.filter(function(item) {
return item !== '';
});
var items = [];
// create a promise to wait for each event
var listeners = eventNames.map(function(eventName) {
return new Promise(function(resolve) {
eventTarget.addEventListener(eventName, function(e) {
items.push(e);
resolve();
}, false);
});
});
// resolve once all events have fired
return Promise.all(listeners).then(function() {
return Promise.resolve(items);
});
}
要点 GitHub
答案 4 :(得分:0)
Promise.all
是要走的路,但为了好玩(以及导入 polyfill 的懒惰),我想出了这个小解决方案:
executedCount = 0
function onExecuted() {
document.body.dispatchEvent(new Event('executedCountIs'+(++executedCount)));
}
function execute_this() {
onExecuted()
}
function execute_sth() {
onExecuted()
}
function main() {
document.body.addEventListener('executedCountIs2', doStuffWhenBothAreReady)
execute_this()
execute_sth()
}
我假设 Javascript 引擎在此处保护我免受竞争条件的影响。