0

使う前は

//get state
   MyClass.prototype.getState = function(key) {
       var value;
       switch(this._options.type){
          case "cookie":
                value = $.cookie(key);
                break;

          case "localStorage":
                value = window.localStorage.getItem(key);
                break;
        }

        this._options.afterGetState(key, value);
        return value;
    };

   //set state
   MyClass.prototype.setState = function(key, value) {
        switch(this._options.type){
          case "cookie":
                $.cookie(key, value); 
                break;

          case "localStorage":
                window.localStorage.setItem(key, value));
                break;
        }
        return this._options.afterSetState(key, value);
      };



    MyClass.prototype.ended = function() {
        return !!this.getState("is_ended");
      };

    MyClass.prototype.setStep = function(value) {
        if (value != null) {
          this._current = value;
          return this.setState("step", value);
        } else {
          this._current = this.getState("step");
          if (this._current === null || this._current === "null") {
            return this._current = 0;
          } else {
            return this._current = parseInt(this._current);
          }
        }
      };

      MyClass.prototype.end = function() {
        this.setState("end", "true");
      };

localStorage と cookie が使用されています。データを db に保存する機能を追加したので、ajax と async 関数を使用する必要があります。だから私はコードを変更しました:

//get state async
   MyClass.prototype.getState = function(key, callback) {
        oldThis = this;
        //h-mmm... what if callback is null or undefined? Will it work for function(){ }?
        callback = typeof callback != 'undefined' ? callback : function(){ }
        switch(this._options.storageType){

          case "cookie":
            setTimeout(function(){ 
                    value = callback($.cookie(key)); 
                    oldThis._options.afterGetState(key, value);
                    return value;
                  },
              0);
            break;

          case "localStorage":
            setTimeout(function(){ 
                  callback(window.localStorage.getItem(key));
                  oldThis._options.afterGetState(key, value);
                  return value;
                },
              0);
            break;

          case "db":
            $.ajax({
                type: "GET",
                url: "/123",
                data: { .... },
                success: function(data){
                  value = callback(data);
                  oldThis._options.afterGetState(key, value);
                  return value;
                },
                error: function() {
                  alert('Error occured');
                  return undefined;
                }
            });
            break;
        }
      };

  //set state async
  MyClass.prototype.setState = function(key, value, callback) {
        oldThis = this;
        callback  = callback || function(){ }
        switch(this._options.storageType){
          case "cookie":
                setTimeout(function(){ 
                        callback($.cookie(key, value)); 
                        return oldThis._options.afterSetState(key, value);
                     },
                0);
                break;

          case "localStorage":
                setTimeout(function(){ 
                      callback(window.localStorage.setItem(key, value));
                      return oldThis._options.afterSetState(key, value);
                    },
                0);
                break;

          case "database":
                $.ajax({
                    type: "POST",
                    url: "123",
                    data: { .... },
                    success: function(data){
                      callback(data);
                      return oldThis._options.afterSetState(key, value);
                    },
                    error: function() {
                        alert('Error occured');
                    }
                });
            break;
        }
      };

それでは、prototype.ended、prototype.setStep、prototype.end 関数を変更するにはどうすればよいでしょうか。これが私がしたことです:

//nothing has been changed. Is this correct? It seems to be so.
MyClass.prototype.ended = function() {
    return !!this.getState("end");
  };

MyClass.prototype.setStep = function(value) {
    if (value != null) {
      this._current = value;
      return this.setState("step", value, function(value){ return value; });
    } else {
        oldThis = this;
        this.getState("step", function(value){ oldThis._current = value; });
      if (this._current === null || this._current === "null") {
        return this._current = 0;
      } else {
        return this._current = parseInt(this._current);
      }
    }
  };

//nothing has been changed. Is this correct as well?
  MyClass.prototype.end = function() {
    this.setState("end", "true");
  };

肝心なのは、どこから値を返す必要があるのか​​\u200b\u200bわからないということprototype.setState and prototype.getStateですprototype.end, prototype.enden and prototype.setStep

4

1 に答える 1

1

非同期操作を扱う場合、returnステートメントの代わりにコールバック関数を使用する必要があります。

たとえば、この同期コードは次のとおりです。

function syncFunc() {
    return 10;
}
var val = syncFunc();
doSomethingWithVal(val);

関数が非同期の場合、次のようになります。

function asyncFunc(callback) {
    setTimeout(function() {
       var data = 10;
       // Call the callback when async op is finished
       callback(data);
    }, 1000);
}
asyncFunc(doSomethingWithVal);

特定のコードに関しては、これは機能しないことを意味します。

MyClass.prototype.ended = function() {
    return !!this.getState("end");
};

from から戻ることはできません(コールバックの前に戻るため、endedおそらく常にが返されます)。もう使えないので、ロジックを再考する必要があります。同じことが にも当てはまります。現在は非同期であるため、 の戻り値を返すことはできません。undefinedgetStatevar x = obj.ended()setStepgetState

于 2013-01-28T13:11:16.823 に答える