在Javascript中将函数更改为同步执行

时间:2015-11-08 18:59:54

标签: javascript google-chrome-extension

我查看了这个示例代码:

function findItem() {
    var item;
    while(item_not_found) {
        // search
    }
    return item;
}

var item = findItem();
// do something with item
doSomethingElse();

我正在尝试将我的Google Chrome扩展程序的代码设置为相同的格式(同步)。

到目前为止我已经

var token = chrome.storage.local.get('token', function (result) {
  var tokens = result.token;
  alert("IN: " + tokens);
  return tokens;
});
alert(token);

但是,这不起作用。它根本不会在函数中打印警报,并且出现的打印声明该标记未定义。

这个异步代码有效:

chrome.storage.local.get('token', function (result) {
  var tokens = result.token;
});

但我需要首先获得令牌的价值,然后继续使用其他代码。

1 个答案:

答案 0 :(得分:3)

似乎对异步代码缺乏了解。返回值实际上与您的示例无关。根据您对token未定义的描述,.get()方法会忽略其回调的返回值。

实际上这就是回调的本质。 chrome.storage.local.get()的建议是使值(在这种情况下为result)仅在回调函数内部不可用。这样做的原因是.get()的行为是在代码继续进行的同时在后台执行某些操作。它不等待任何事情,因此在调用alert()时,token变量被赋予.get()的返回值,这是未定义的。

没有回调就无法打破这种局面。而是将您的代码放在回调中(请参阅callback hell了解为什么这可能是一个问题)。

另外,您可以使用promises

来使其更清洁
function promisedToken() {
  return new Promise(function(resolve, reject) {
    chrome.storage.local.get('token', resolve);
  })
  .then(function(result) {
    var tokens = result.token;
    alert("IN: " + tokens);
    return tokens;
  });
}

promisedToken()
  .then(function(token) {
    alert(token);
  });

有关回调的更多信息:https://github.com/maxogden/art-of-node#callbacks

更新:根据评论,我认为您所寻找的是编码风格/架构的一些指导。由于这是Chrome扩展程序,因此我们知道支持Promises

有一个库可以为chrome.storage.local提供承诺API:https://www.npmjs.com/package/chrome-storage-promise

为清楚起见,可以手动完成:

在你的情况下,创建一个返回promise的泛型函数:

function promisedGet(key) {
  return new Promise(function(resolve, reject) {
    chrome.store.local.get(key, function(result) {
      if (chrome.runtime.lastError)
        reject(chrome.runtime.lastError);
      } else {
        resolve(result);
      }
    });
  });
}

然后在你的代码中,这是一个简单的问题:

var promisedResults = promisedGet('token');
var promisedTokens = promisedResults.then(function(result) {
  return result.tokens;
});
promisedTokens.then(function(tokens) {
  alert(tokens);
  return tokens;
});

可以轻松简化:

promisedGet('token')
  .then(function(results) {
    alert(results.tokens);
    return results.tokens;
  });

您可以将任意数量的链式结果或函数用于某个目的。关键区别在于需要结果的任何代码都在.then()函数内执行。如果其中任何一个抛出错误,则错误逻辑进入.catch()函数。这种编程风格非常富有表现力和可组合性。