在For循环之前异步获取/获取请求

时间:2020-01-25 17:53:50

标签: javascript

我是Java的新手,正在尝试使Images动态地将其自身添加到'addCache'。

然后我将其与服务工作者一起使用,以将其添加到缓存中。

我的sw.js文件如下:

    var product = [];
    fetch('http://localhost:3000/api/products')
    .then(res => res.json())
    .then(json => product = json)


//Caching Files


  var cacheName = 'pwa-v1';
  var toCache= [
      '/PW1/',
      '/PW1/Apps/calculate.js',
      '/PW1/Apps/login.js',
      '/PW1/Apps/index.js',
      '/PW1/index.html',
      '/PW1/products.html',
      '/PW1/style.css',

];


var productImages = [];

for(var i=0;i<product.length;i++){
    productImages.push('/PW1/img/'+product[i].name+'.jpg');
}
  var addCache = toCache.concat(productImages);

self.addEventListener('install', function(s) {

.............
.............
.............

我的目标是使获取请求异步,它从后端获取数据并将其存储到产品数组中。我希望 for循环等待 product ,然后开始循环。我该怎么做呢?

for循环仅获取产品名称,该名称与映像名称相同。

目前,它没有添加任何图像来添加缓存。但是它确实添加了其余文件。

任何帮助将不胜感激。 提前致谢。

5 个答案:

答案 0 :(得分:1)

因为它是异步fetch()函数,所以必须将处理响应数据的代码放入then()函数中

var products = [];
fetch('http://localhost:3000/api/products')
    .then(res => res.json())
    .then(json => products = json)
    .then(() => {
       // ... treatement of product datas ...
       for(var i=0;i<products.length;i++){
         productImages.push('/PW1/img/'+products[i].name+'.jpg');
       }
     })
   .catch((e) => {
       console.log('Error', e);
    });

对于ES6 JavaScript语法,我建议您对JS中的异步代码使用糖语法“ async-await”。它可以帮助您编写异步代码,例如同步代码。可以肯定的是,同步代码更容易理解。您应该在StackOverFlow的另一个著名主题中检查我的答复的详细信息:How do I return the response from an asynchronous call?

答案 1 :(得分:1)

fetch是异步的,因此您需要创建一个callback并通过调用then来运行,并完成所有依赖于调用API的响应的工作:

// ...

var cacheName = "pwa-v1"
var toCache = ["/PW1/", "/PW1/Apps/calculate.js", ...]

fetch("http://localhost:3000/api/products")
  .then(res => res.json())
  .then(createFileCache)
  .catch(handleError)

function createFileCache(items) {
  var productImages = items.map(
    function(item) {
      return `/PW1/img/${item.name}.jpg`
    }
  )
  toCache.concat(productImages)
}

function handleError(err) {
  // handle errors appropriately
}

// ...

请记住,这是异步的,因此,如果您需要在其他地方依赖toCache的新状态,则可能需要将另一个回调添加到组合中。

答案 2 :(得分:1)

使用async/await。作为保证,它保证将通过await关键字返回对请求数据的响应或拒绝。

在下面的演示中,异步函数getPaths()将传递一个终结点(即JSON的url)和一个可选数组(即缓存的路径)。它返回所有给定路径的数组。端点是实时测试服务器的端点,因此使用自己的端点对其进行测试应该没有问题。如果您这样做...那么您应该认真研究后端或服务人员。

演示

let toCache = [
  '/PW1/',
  '/PW1/Apps/calculate.js',
  '/PW1/Apps/login.js',
  '/PW1/Apps/index.js',
  '/PW1/index.html',
  '/PW1/products.html',
  '/PW1/style.css'
];

const getPaths = async(endpoint, cache = []) => {
  const response = await fetch(endpoint);
  let data = await response.json();

  data = cache.concat(data.map(product => `/PW1/img/${product.username}.jpg`));
  return data;
}

getPaths('https://jsonplaceholder.typicode.com/users', toCache).then(data => console.log(data));

答案 3 :(得分:0)

您需要将for循环放入函数中,作为Promise fetch返回的.then方法的参数,就像您的json转换函数一样

类似的东西:

var product = [];
var productImages = [];


fetch('http://localhost:3000/api/products')
.then(res => res.json())
.then(json => product = json)
.then(
   function() 
   {
         for(var i=0;i<product.length;i++)
         {
            productImages.push('/PW1/img/'+product[i].name+'.jpg');
         }         
   }
)

答案 4 :(得分:0)

const toCache= [
      '/PW1/',
      '/PW1/Apps/calculate.js',
      '/PW1/Apps/login.js',
      '/PW1/Apps/index.js',
      '/PW1/index.html',
      '/PW1/products.html',
      '/PW1/style.css',
];
const productImages = [];
fetch('http://localhost:3000/api/products')
    .then(res => res.json())
    .then(products => {
        for (const product of products) {
            productImages.push('/PW1/img/' + product.name + '.jpg');
        }
        let addCache = toCache.concat(productImages);
        // your logic can continue here
    });

尝试不使用varlet更好,而您的情况const更好,因为它的限制更严格

相关问题