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 调用,从这个意义上说,当我尝试将其值分配给数据 [“userID”] 时,它不会及时返回。

我想我可以通过先执行 userID 调用然后使用它的回调(这里的术语有点模糊)继续添加到数据数组来解决这个问题。

我不知道这是否是正确的方法。如何获得要使用的异步函数的返回?

4

4 回答 4

3

更仔细地查看文档中的 invokeAsync 示例。

在您的代码中,您有两个错误invokeAsynckango.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 回答