1

これを尋ねる私の理論は少し弱いかもしれませんので、お気軽にお知らせください。

このコードは、Kango フレームワークを使用するブラウザ プラグインの一部です。基本的に、ユーザー ID であるランダムな文字列を生成するコードがあります。大きな ole JSON を設定する別の関数もあります。次のようになります。

function createJSON() {
data = {};
data["userID"] = generateID();
}

function generateID() {
kango.invokeAsync('kango.storage.getItem', 'userID', function(data) {
    uid = data;

    if (!uid) {
      console.log("uid doesn't exist, creating uid!");
      kango.invokeAsync('kango.storage.setItem', userID, function(data) { return data; });
    } else {
      console.log("uid found!: " + uid);
      return uid;
    }

    return data;
  });
}

kango.invokeAsync のドキュメントはこちらです。私の理解では、それは非同期の ajax 呼び出しのように機能し、その意味で、その値を data["userID"] に割り当てようとしているときにちょうど間に合わないということです。

最初に userID 呼び出しを実行してから、そのコールバック (ここでは用語が少しあいまいです) を使用して先に進み、データ配列に追加することで、これを解決できると思います。

それが正しい方法かどうかはわかりませんが。非同期関数の戻り値を取得するにはどうすればよいですか?

4

4 に答える 4

3

ドキュメントのinvokeAsyncの例をさらに詳しく見てみましょう。

あなたのコードでは、2つの間違いがinvokeAsyncあり、次のようにkango.storage.setItem呼び出します。

// 1. Second argument should be string 'item name'
// 2. Third argument should be 'item value'
kango.invokeAsync('kango.storage.setItem', userID, function(data) { callback(data); });

次のようにkango.storage.setItemを使用する必要がありますinvokeAsync

kango.invokeAsync('kango.storage.setItem', 'userID', '123');    

したがって、結果コードは次のようになります。

function generateID(callback) {
    kango.invokeAsync('kango.storage.getItem', 'userID', function(uid) {
        if(!uid) {
            kango.console.log("uid doesn't exist, creating uid!");
            uid = '123'; // TODO: replace with your ID generation algorithm
            kango.invokeAsync('kango.storage.setItem', 'userID', uid);
        }
        else {
            kango.console.log("uid found!: " + uid);
        }
        callback(uid);
    });
}

data = {};
generateID(function(uid) {
    data["userID"] = uid;
});
于 2012-06-23T08:26:46.020 に答える
2

generateID() の非同期性のため、このようにすることはできません。非同期呼び出しが終了する前に返されるため、データは利用できません。

data["userID"] = generateID();

代わりに、次のようなコールバックを使用する必要があります。

generateID(function(val) {data["userID"] = val;});

function generateID(callback) {
kango.invokeAsync('kango.storage.getItem', 'userID', function(data) {
    uid = data;

    if (!uid) {
      console.log("uid doesn't exist, creating uid!");
      kango.invokeAsync('kango.storage.setItem', userID, function(data) { callback(data); });
    } else {
      console.log("uid found!: " + uid);
      callback(uid);
    }

  });
}

非同期関数を使用する場合、通常の順次プログラミングは使用できません。代わりに、完了コールバックで実行フローを続行する必要があります。これは、非同期関数の結果が既知であるためです。

createJSON()したがって、そこから目的の値を呼び出して返すことはできません。後のコードでcreateJSON()結果が必要な場合は、それもコールバックに含める必要があります。

于 2012-06-23T02:44:10.917 に答える
1
function createJSON() {
  data = {};
  generateID(function(id) {
    data["userID"] = id;
  });
}

function generateID(callback) {
  kango.invokeAsync('kango.storage.getItem', 'userID', function(data) {
  uid = data;

  if (!uid) {
    console.log("uid doesn't exist, creating uid!");
    kango.invokeAsync('kango.storage.setItem', userID, function(data) { callback(data); });
  } else {
    console.log("uid found!: " + uid);
    callback(uid);
  }

  callback(data);
});
}

これはうまくいきますか?

于 2012-06-23T02:47:51.463 に答える
1

非同期呼び出しからオブジェクトを返すことはできません。代わりに、別の関数を作成し、コールバック オブジェクトをそれに渡します。

// some code
if (!uid) {
  console.log("uid doesn't exist, creating uid!");
  kango.invokeAsync('kango.storage.setItem', userID, function(data) { 
    getData(data); 
  });
} else {
  console.log("uid found!: " + uid);
  getData(uid);
}

function getData(data) {
    // Use data here.
}
于 2012-06-23T02:50:38.503 に答える