无法从表格 API 到 WooCommerce REST API 应用程序中循环获取数据

Trouble looping data from fetch, in a Sheets API to WooCommerce REST API App

我有一个在 Google GAS 内部使用的代码,但我必须对其进行一些重构才能在外部使用它,而且我在使用 for 循环时遇到了问题,我必须形成一个数组。 我将通过在开发环境中读取 API 键使代码可重现。

    
    const optionsGet = {
    'method': 'GET',
    'contentType': 'application/x-www-form-urlencoded;charset=UTF-8',
    'muteHttpExceptions': true,
};
    const website = 'https://atopems-desarrollo.com.ar';
    const ck = 'ck_112e7b278d5731d2cdb44a57c07bbeab2fc9196a';
    const cs = 'cs_e891f6cd193608f47f8acf340b985317448cdca4';
    var container = [];
    var surl = website + '/wp-json/wc/v3/products?consumer_key=' + ck + '&consumer_secret=' + cs + '&per_page=20' + '&orderby=id' + '&order=asc' + '&status=publish' + '&page=20';
    var url = surl
    console.log(url)


    var fetchCall = fetch(url, optionsGet)
        .then(response => {
            if (response.ok) {
                return response.json()
            } else {
                throw new Error('beep-boop no dio 200 OK' + response.status);
            }
            console.log(Error);
        })

    var total_pages = 40;
    var pages_count = 20;
    while (pages_count < total_pages) {
        pages_count++;
        fetchCall
            .then(data => {
                for (var i = 0; i < data.length; i++) {
                    //console.log(i);
                    container.push({
                        sku: data[i]['sku'],
                        id: data[i]['id'],
                        price: data[i]['price']
                    });
                }
            })
        console.log(container);
        var surl = website + '/wp-json/wc/v3/products?consumer_key=' + ck + '&consumer_secret=' + cs + '&per_page=20' + '&orderby=id' + '&order=asc' + '&status=publish' + '&page=' + (pages_count + 1);
        var url = surl
        console.log(url);
        var fetchCall = fetch(url, optionsGet)
            .then(response => {
                if (response.ok) {
                    return response.json()
                } else {
                    throw new Error('beep-boop no dio 200 OK' + response.status);
                }
                console.log(Error);
            })
    }

现在的代码片段在其功能中。 我无法弄清楚如何使用 fetch 并在 while 中获取数据以及如何使用 for 循环将其推送到空数组。以下代码段是我认为它应该如何工作的?

const optionsGet = {
        'method': 'GET',
        'contentType': 'application/x-www-form-urlencoded;charset=UTF-8',
        'muteHttpExceptions': true,
    };
        const website = 'https://atopems-desarrollo.com.ar';
        const ck = 'ck_112e7b278d5731d2cdb44a57c07bbeab2fc9196a';
        const cs = 'cs_e891f6cd193608f47f8acf340b985317448cdca4';
        var container = [];
        var surl = website + '/wp-json/wc/v3/products?consumer_key=' + ck + '&consumer_secret=' + cs + '&per_page=20' + '&orderby=id' + '&order=asc' + '&status=publish' + '&page=20';
        var url = surl
        console.log(url)


        var fetchCall = fetch(url, optionsGet)
            .then(response => {
                if (response.ok) {
                    return response.json()
                } else {
                    throw new Error('beep-boop no dio 200 OK' + response.status);
                }
                console.log(Error);
            })
        var preVal = [];
        var total_pages = 40;
        var pages_count = 20;
        while (pages_count < total_pages) {
            pages_count++;
            fetchCall
                .then(data => {
                  preVal.push(...data);
                })
            for (var i = 0; i < preVal.length; i++) {
                        //console.log(i);
                        container.push({
                            sku: preVal[i]['sku'],
                            id: preVal[i]['id'],
                            price: preVal[i]['price']
                        });
                    }    
            console.log(container);
            var surl = website + '/wp-json/wc/v3/products?consumer_key=' + ck + '&consumer_secret=' + cs + '&per_page=20' + '&orderby=id' + '&order=asc' + '&status=publish' + '&page=' + (pages_count + 1);
            var url = surl
            console.log(url);
            var fetchCall = fetch(url, optionsGet)
                .then(response => {
                    if (response.ok) {
                        return response.json()
                    } else {
                        throw new Error('beep-boop no dio 200 OK' + response.status);
                    }
                    console.log(Error);
                })
        }

但是 preVal 将是空的,因为它会在我尝试执行 for 循环时被填充。

我对 JS 和一般编程还很陌生。到目前为止,我已经阅读了一些关于承诺的内容,但我无法理解。

我需要的是用于创建新数组的 for 循环,因为其余代码只想使用 WC 响应中的那 3 个值。

谢谢。

所以,我用 async / promise 解决了这个问题。

const ck = 'XXX'

const cs = 'XXX'

const website = 'XXX'

const optionsGet = {
                    method: 'GET',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'                   
                    }
                  };


async function batchWooUpdate() {
  gapi.client.sheets.spreadsheets.values.get({
    spreadsheetId: 'XXXXXXXXX',
    range: 'XXXXXXXXXX',  
  }).then(async function(response) {    
    var range = response.result;
    if (range.values.length > 0) {
            var surl = website + '/wp-json/wc/v3/products?consumer_key=' + ck + '&consumer_secret=' + cs + '&per_page=100' + '&orderby=id' + '&order=asc' + '&status=publish' + '&page=';
            var url = surl;
            var toUpdate = [];
            for (i = 0; i < range.values.length; i++) {
                    var row = range.values[i];
                    toUpdate.push({
                        sku: row[0],                        
                        price: row[1]
                    });
                  }
                  console.log(toUpdate);

            let allData = [];
            let morePagesAvailable = true;
            let total_pages = 300;
            let currentPage = 0;
            let container = [];
            while (morePagesAvailable) {
                currentPage++;
                const response = await fetch(`${url}${currentPage}`, optionsGet);
                let data = await response.json();
                morePagesAvailable = currentPage < total_pages;
                allData.push(...data);
            }
            for (var i = 0; i < allData.length; i++) {
                //console.log(i);
                container.push({
                    sku: allData[i]['sku'],
                    id: allData[i]['id'],
                    price: allData[i]['price']
                });
            }
            console.log(container);
            await console.log(allData);


            var data_obj = {}
            for (let obj of toUpdate)
                data_obj[isNaN(obj.sku) ? obj.sku.toUpperCase() : obj.sku] = {
                    'price': obj.price
                };

            console.log(data_obj);

            var container_obj = {}
            for (let obj of container)
                container_obj[isNaN(obj.sku) ? obj.sku.toUpperCase() : obj.sku] = {
                    'price': obj.price,
                    'id': obj.id
                };

            console.log(container_obj);

            var output = [];
            for (let sku in container_obj) {
                let data_subObj = data_obj[sku];
                let container_subObj = container_obj[sku];
                if (data_subObj && data_subObj.price != container_subObj.price) {
                    output.push({
                        'id': container_subObj.id,
                        'regular_price': data_subObj.price
                    });
                }
            }

            console.log(output);

            var temporary, chunk = 100;
            for (let i = 0; i < output.length; i += chunk) {
                temporary = output.slice(i, i + chunk);
                var payloadUp = {
                    update: temporary
                };

                console.log(payloadUp);

                var urlPost = website + '/wp-json/wc/v3/products/batch?consumer_key=' + ck + '&consumer_secret=' + cs;
                console.log(urlPost);
                let updateRes = await fetch(urlPost, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json;charset=utf-8'
                    },
                    body: JSON.stringify(payloadUp)
                });                
                let updateText = await updateRes.text();
                console.log(updateText);
            }
      } else {
      appendPre('No data found.');
    }
  }, function(response) {
    appendPre('Error: ' + response.result.error.message);
  });

这是使用谷歌 sheet API 库。

@Peter Pajchl 指出的我之前的问题

是不是 fetch 本身是异步的,我没有让进程完成(这是我的初步理解)。

所以我做了一个异步函数,然后在提取中使用 await 让它完成,在 response.json() 中,使用简单的 while 分页并将提取中的所有数据推送到一个空的while 循环外的数组。 然后基本处理好了。

我认为我的下一步是做一系列承诺并用 Promise.all

解决它们

但现在,我有点害怕。