14

私は現在、主に独学の目的でアプリを開発していますが、まだjsに完全に慣れていないため、問題の解決に役立つ可能性があります。

私のアプリでは、DOM操作、ページ遷移、ajax呼び出しなどに使用されるJavascriptライブラリ(jqMobi)を使用しています。また、ジオロケーションなどのデバイス機能にアクセスするためにphonegapを使用しています。

アプリを起動したら、デバイスのジオロケーションを取得したいので、サーバーにajax(jsonp)リクエスト(デバイスのジオロケーションを含む)を送信します。これにより、リストの作成に使用するJSONオブジェクトの配列が返されます。 。

ジオロケーションを取得する前に、phonegapがロードされるのを待つ必要があります。そして、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を使用しますが、これらにアクセスできないため、別の方法を探しています。

4

5 に答える 5

25

一見すると、このようなものは間違いなく機能します:

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!
  }
}

ただし、拡張可能ではありません(3番目のイベントを待機させたい場合はどうなりますか?)。カウンターは機能します:

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つのより高いレベルの抽象化です。

于 2012-12-19T20:44:34.417 に答える
15

イベントが発生したときに解決するPromiseを作成し、両方の準備が整うのを待つことができます。

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
});
于 2019-07-09T00:30:47.793 に答える
1

これを試して、

document.addEventListener("DOMContentLoaded",execute_this,false);
function execute_this(){
document.addEventListener("deviceready", execure_sth, false);
}
function execute_sth(){
//your code here
}
于 2012-12-19T20:44:21.920 に答える
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の要点

于 2021-02-07T14:41:05.553 に答える
0

Promise.all行く方法ですが、楽しみのために(そしてポリフィルをインポートするのが面倒なので)、私はこの小さな解決策を思いつきました:


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エンジンが競合状態から私を保護していると思います。

于 2021-05-11T14:11:05.237 に答える