使用`callback`

时间:2018-05-28 08:15:21

标签: 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)]。这就是为什么每次只导致api调用时代码的if部分运行,导致else部分过时。

我从围绕callback的许多着名问题中了解了asynchronous calls,但没有一个与callbacks连接本地存储。在实现callback之前,newItemList已存储在本地存储中,但我无法第一次从JSON响应中获取obj,这是asynchronous calls的典型行为。 建议编辑,如果有的话。

2 个答案:

答案 0 :(得分:1)

在调用apiCall来电的功能(即初始值为item.itemList)之前,系统正在执行此行:

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

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

因此,如果您将这一行移到这些回调函数中,在您发生变异newItemList之后,set上的chrome.storage.local调用将执行所应用的更改(例如{ {1}}):

newItemList.push([item,d.getHours(),result])

答案 1 :(得分:1)

我认为当执行到达 chrome.storage.local.set({itemList:newItemList}); 行时,该变量尚未设置,因为 XMLHttpRequest 异步你需要在回调函数中添加 chrome.storage.local.set 或使用promise然后设置本地存储值