0

私はJavaScriptプログラミングが初めてです。私はうまくいく答えを見つけることができません。

問題は、私の関数が次のように setTimeout 呼び出しでラップされている場合にのみ機能することです。

var sPageIdentifier = 'ReportViewer';
UserPreferencesManager.Initialize(sPageIdentifier);
setTimeout(function () {
var strUserPrefs = UserPreferencesManager.GetPreferences();
    console.log(strUserPrefs);
   initLayout(strUserPrefs);
}, 1000);

function initLayout(strUserPrefs) {
    //do stuff using strUserPrefs
}

setTimeout 関数をコメントアウトすると、strUserPrefs が null であるため、initLayout(strUserPrefs) が失敗します。どんな助けでも大歓迎です!

UserPreferencesManager.js コードは次のとおりです。

var UserPreferencesManager = function () {
  var strPrefsID = null;
  var strPrefsString = null;

  return {

    Initialize: function (strPrefsIDIn) {
      strPrefsID = strPrefsIDIn;
      strPrefsString = this.GetPreferences();
    },

    GetPreferences: function () {
      if (!strPrefsID) {
        alert("Validation Failed: the UserPreferencesManager must be initialized prior to usage.");
        return null;
      }
      if (!strPrefsString) {
        this.LoadPreferences();
        return strPrefsString;
      }
      return strPrefsString;
    },
    LoadPreferences: function () {
      if (!strPrefsID) {
        alert("Validation Failed: the UserPreferencesManager must be initialized prior to usage.");
        return null;
      }    
      myasyncfunctioncall({
        parameters: ["USR_PersonId", "abc", 'GET']
        script_name: 'MAINTAIN_USER_PREFS',
        onexception: function (exception, xhr, options) {
          alert('Error: ' + xhr.statusText + +exception);
          console.log(exception);
        },
        onsuccess: function (data, xhr, options) {
          if (data == "User ID is zero") {
            alert('MP_MAINTAIN_USER_PREFS: must be > 0.0');
            strPrefsString = data;
          }
          else {
            strPrefsString = data;
          }
        }
      });
    },// end of LoadPreferences

    WritePreferences: function (strPrefsIn, strPrefsID) {
      if (strPrefsID && typeof strPrefsID === "string") {
        if (strPrefsIn != null) {

          myasyncfunctioncall({
            parameters: ["USR_PersonId", strPrefsID, strPrefsIn , 'SET']
            script_name: 'MAINTAIN_USER_PREFS',
            onexception: function (exception, xhr, options) {
              alert('Error: ' + xhr.statusText + +exception);
              console.log(exception);
            },
            onsuccess: function (data, xhr, options) {
              if (data == "transaction-ok") {
                UserPreferencesManager.LoadPreferences();
              } else if (data == "User ID is zero") {
                alert('MP_MAINTAIN_USER_PREFS: must be > 0.0');
              }
            }
          });
        } else {
          alert("Error: Preferences object must be initialized prior to writing preferences");
        }
      } else {
        alert('Error: The preference ID can\'t be null and must to be of type string');
        return;
      }
    }// end of WritePreferences
  };// end of return API

}(); // end of UserPreferencesManager
4

3 に答える 3

0

この myasyncfunctioncall が非同期リクエストを送信しているように見えます。この非同期リクエストの応答が到着した場合に設定する変数を追加する必要があります。設定されたら、ルーチンを続行できます。

JavaScript で非同期呼び出しが行われると、プログラムは既に完了したかのように続行されます。完了したかどうかを確認するには、手動でチェックを追加する必要があります。

于 2013-07-11T17:26:00.753 に答える
0

UserPreferencesManager.GetPreferences() は、非同期 AJAX 呼び出しを行ってユーザー設定を取得します。したがって、この場合、Javascript スレッドは現在のスレッド コンテキストで実行を継続し、initLayout(strUserPrefs) を実行します。しかし、この状態では GetPreferences() 呼び出しはまだ完了しておらず、strUserPrefs は null です。

SetTimeout は、この問題を克服するためのトリックの 1 つです。ただし、非同期 AJAX 呼び出しごとにコールバック関数を実行できるように API を設計することもできます。

于 2013-07-11T17:28:43.780 に答える
0

ヒントをありがとう、バラチャンドラ!LoadPreferences メソッドに callback と strPrefsID の 2 つのパラメーターを追加したので、成功時に fnCallback 関数を呼び出して ajax データを渡すことができます。

LoadPreferences: function (fnCallback, strPrefsID) {
    if (!strPrefsID) {
        alert("Validation Failed: the BhsUserPreferencesManager must be initialized prior to usage.");
        return null;
    }
    if (strPrefsString) {
        // strPrefsString is not null, so return it
        callback(strPrefsString);
    } else {
        myasyncfunctioncall({
            parameters: ["USR_PersonId", "abc", 'GET']
            script_name: 'MAINTAIN_USER_PREFS',
            onexception: function (exception, xhr, options) {
                alert('Error: ' + xhr.statusText + +exception);
                console.log(exception);
            },
            onsuccess: function (data, xhr, options) {
                if (data == "User ID is zero") {
                    alert('MAINTAIN_USER_PREFS: must be > 0.0');
                    strPrefsString = data;
                } else if (data.substring(0, 5) === "ERROR") {
                    alert(data);
                } else {
                    fnCallback(data);
                }
            }
        });
    }
}// end of LoadPreferences

initLayout を呼び出す方法は次のとおりです。

BhsUserPreferencesManager.LoadPreferences(initLayout, sPageIdentifier);
于 2013-07-12T13:09:46.073 に答える