javascript - 使用 `localStorage` 时,数组不会存储在 `callback` 中

标签 javascript asynchronous google-chrome-extension

我正在尝试存储 item在数组中,newItemList ,以及当前时间和一个对象,我从服务器作为 JSON 响应获取该对象,并将其解析为 js 对象。这仅仅意味着 newItemList 的典型元素将是[item, 13(present_hour), obj]

这是代码,

 var item;
 //some code to obtain item

 chrome.storage.local.get({'itemList':[]}, function(item){
   var newItemList = item.itemList;
   var d = new Date();

   if (isItemInArray(newItemList,item) == -1) {
     //api call function as callback

     apiCall(function(result){
         newItemList.push([item,d.getHours(),result]);
     });

   } else {
     var indexOfitem = findItem(newItemList,item);//finding item in the array
     if(//some condition){

       apiCall(function(result){
           newItemList[indexOfTab][1] = d.getHours();
           newItemList[indexOfTab][2] = result;
       });

     } else {
       var indexOfitem = findItem(newItemList,item);
       storedApiCall(newItemList[indexOfTab][2]);//sending the stored JSON response
     }
  }
 chrome.storage.local.set({itemList: newItemList});
 })

 function apiCall(callback){
    //API call, to obtain the JSON response from the web server
   var xhttp = new XMLHttpRequest();
   xhttp.onreadystatechange = function() {
   if (this.readyState == 4 && this.status == 200) {
     var myObj = JSON.parse(this.responseText);//parsing the JSON response to js object

      callback(myObj);
      storedApiCall(myObj);//this function just works fine
     }
    };
  xhttp.open("GET", "example.com", true);
  xhttp.send();
 }

newItemList没有存储在本地存储中。它仅包含一个元素 [item, present hour, obj(from present apiCall)] 。这就是为什么,只有if部分代码每次运行都会导致 api 调用,从而呈现 else部分已过时。

我读到了callback来自周围询问的许多著名问题asynchronous calls ,但没有一个将本地存储与 callbacks 连接起来。实现之前callback , newItemList存储在本地存储中,但我第一次无法从 JSON 响应中获取 obj,这是 asynchronous calls 的典型行为。 建议修改(如果有)。

最佳答案

此行在调用 apiCall 所提供的函数之前执行(即使用其初始值 item.itemList):

chrome.storage.local.set({itemList: newItemList});

这是因为回调通常是在某些异步操作完成后调用的。在您的情况下,它们将在 apiCall 执行的任何操作完成后被调用,例如收到对 API 的 HTTP 响应。

因此,如果您将该行移动到这些回调函数中,则在您修改 newItemList 之后,在它们的末尾,对 chrome.storage.local< 的 set 调用 将在应用更改后执行(例如 newItemList.push([item,d.getHours(),result])):

chrome.storage.local.get({'itemList':[]}, function(item){
    var newItemList = item.itemList;
    var d = new Date();

    if (isItemInArray(newItemList,item) == -1) {
      //api call function as callback

      apiCall(function(result){
          newItemList.push([item,d.getHours(),result]);
          chrome.storage.local.set({itemList: newItemList});
      });

    } else {
      var indexOfitem = findItem(newItemList,item);//finding item in the array
      if(//some condition){

        apiCall(function(result){
            newItemList[indexOfTab][1] = d.getHours();
            newItemList[indexOfTab][2] = result;
            chrome.storage.local.set({itemList: newItemList});
        });

      } else {
        var indexOfitem = findItem(newItemList,item);
        storedApiCall(newItemList[indexOfTab][2]);//sending the stored JSON response
      }
    }
})

关于javascript - 使用 `localStorage` 时,数组不会存储在 `callback` 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50561899/

相关文章:

wcf - 来自 Silverlight 的异步 WCF 调用

javascript - Angular2 中回调函数中作用域变量的访问值

javascript - Chrome 扩展 -executeScript 不在事件选项卡中

google-chrome - "http://*/*"、 "https://*/*"和 "<all_urls>"在 Chrome 扩展程序的权限上下文中意味着什么

javascript - 如何防止某些字符从 React 输入标签中删除?

javascript - 无法生成体素球体

javascript - 在 "Select"上更新在新选项卡中打开网址...仅一次

javascript - jQuery/JavaScript : Using a JavaScript array in jQuery

c# - 任务未等待完成且错误超时协议(protocol)错误 2504

javascript - 无法在打包的 Chrome 扩展程序中获取正确的资源文件路径