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

Changing a Function into a synchronous execution in Javascript

本文关键字:同步 执行 函数 Javascript      更新时间:2023-09-26

我已经浏览了这个示例代码:

function findItem() {
    var item;
    while(item_not_found) {
        // search
    }
    return item;
}
var item = findItem();
// do something with item
doSomethingElse();

我试图让我的googlechrome扩展的代码采用相同的格式(同步)。

到目前为止,我有

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;
});

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

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

事实上,这就是回调的本质。chrome.storage.local.get()的建议是使值(在本例中为result)仅在回调函数内部可用,而不是在回调函数外部可用。原因是.get()的行为是在代码继续运行的同时在后台做一些事情。它不等待任何事情,因此在调用alert()时,token变量被分配了未定义的.get()的返回值。

如果没有回调,就没有办法解决这个问题。相反,将代码放在回调中(请参阅回调地狱,了解为什么会出现问题)。

顺便说一句,你可以通过使用承诺来让这个更干净:

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);
      }
    });
  });
}

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

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()函数。这种编程风格非常有表现力和可组合性。