5

パラメータを取り、同期読み込みを行う関数があります。

非同期のjQuery.ajax呼び出しを実行してデータを取得し、コールバックを呼び出すように変更しました。古いコード(変更できません)は同じ関数を使用して失敗します。非同期コードが実行を継続できるように、また古い同期コードがキャッシュされたデータを取得できるように、データを双方向で取得できる必要があります。これは、非同期でデータが既に読み込まれている場合、同期で読み込まれる場合、または既に実行されている非同期リクエストを待つ場合です。

var ajaxQueries = {}
loadEngineData(fileId, callback) {
    var sync = callback == undefined;
    if (ajaxQueries[fileId]) {
        if (sync) {
            //Need to stop here and wait for ajaxQueries[fileId] to finish
            //Execution cannot continue! If we return before defered has ended here 3rd party scripts will fail.
            return data;
        }
        else {
            ajaxQueries[fileId].done(function(data){callback(data)});
        }
    }
    else {
        ajaxQueries[fileId] = $.ajax({
            async:!sync,
            type:'GET',
            url:fileId2Name(fileId),
            data:null,
            dataType:'text',
        });
        if (sync) {
            var _data = undefined;
            ajaxQueries[fileId].done(function(data){_data=data});
            return _data;
        }
        ajaxQueries[fileId].done(function(data){callback(data);});
    }
}

古いスクリプトが関数を呼び出す場合、ajaxクエリは同期的に実行され、後続のすべての呼び出しは遅延を使用し.done.failすべてが正常になります。

var enginePhyData = loadEngineData('physics');
//Do stuff

新しいスクリプトが最初に関数を呼び出し、この読み込み中に古いスクリプトが同じファイルからデータを読み込もうとすると、の遅延ajaxクエリajaxQueries[fileId]が非同期で実行され、データの読み込みが完了するまで待つ必要があります。既存のライブラリを壊さないようにするため。

loadEngineData質問に焦点を合わせ続けるために簡略化しました。それ以外の場合は、もう少し複雑になり、ファイルのリストを呼び出して並行してロードできます

loadEngineData(['geometry', 'scripts'], function() {
    var phy = loadEngineData('physics');
    var geo = loadEngineData('geometry');
    var scr = loadEngineData('scripts');

    //run the async function;
});
loadEngineData('physics', function() {
    //run the async function;
});

//...
//in the scripts file

var phy = loadEngineData('physics');
//here phy might be undefined if this file went through eval() before `loadEngineData('physics',...)` was called;

コードを最新化することはできますが、問題は、一部のファイルがプロジェクト間で共有され、異なる環境で実行されることです。現在、依存関係をフォークせずに古いスクリプトを変更することはできません。

4

2 に答える 2

5

非同期のajax呼び出しが終了するのを待っている間は、javascriptの実行を停止することはできません。Javascriptは単にそのようには機能しません。

代わりに、プログラムの方法を作り直して、非同期のajax呼び出しが完了するのを待ちたいコードが、ajax呼び出しの実行後に同期的にではなく、コールバック関数を介して実行されるようにする必要があります。

于 2013-01-21T18:10:03.917 に答える
1

終了しました。同期リクエストの場合は、responseTextを返す必要があります。

return data

になります

return ajaxQueries[fileId].responseText;

リクエストは同期的だったので、待つ必要はありません。ブラウザはすでにレスポンスを待っています。

var ajaxQueries = {}
loadEngineData(fileId, callback) {
    var sync = callback == undefined;
    if (ajaxQueries[fileId]) {
        if (sync) {
            return ajaxQueries[fileId].responseText;
        }
        else {
            ...
于 2013-01-21T18:54:36.253 に答える