0

请温柔!纽比试一试。我正在使用 node.js(第一次)

我有一个大的(10,000 行)XML 文件,我需要翻阅它并在 smartsheets 的 50 列中生成大约 900 行。我需要保留来自 XML 文件的顺序(重要)。

我有代码工作,以便它读取 xml 文件,并可以写入行/列,但显然我生成更新输入的速度比 smartsheet 可以处理的快,所以我尝试了承诺。我似乎无法破解它,并希望您能提供任何帮助。系统生成所有记录,但在尝试将它们写入 smasrtsheet 并且订单全部填满时阻塞。

如果你能提出更好的方法,很高兴被告知我在找错树。

提前致谢。

杰尔吉。

3个代码块:

  1. testing.js 文件(脚本本身)

  2. testing.xml(非常精简的 xml 文件版本)

  3. testing.xsd(xml 模式文件)。

  4. 测试.js


 // Initialize the client
var client = require('smartsheet');
var smartsheetClient = client.createClient({
  accessToken: '<insert your own access token before you run>', // use your access code
  logLevel: 'info'
});

 var fs= require('fs'),
 xml2js = require('xml2js');
 const parser = new xml2js.Parser();
 const xpath = require('xpath'),
 dom = require('xmldom').DOMParser;
 fs.readFile('testing.xml',function(err , data){
    var doc = new dom().parseFromString(data.toString(), 'text/xml');
    var select = xpath.useNamespaces('testing.xsd');
     if(err){
     //display error
     }
     else{
         for (var i=0; i < 10 ; i++ ){
            var rowcounter=i+1;
            var identifier = select('//Identifier/text()', doc)[i].nodeValue;
            var revision = select('//Revision/text()', doc)[i].nodeValue;
            var updated = select('//Updated/text()', doc)[i].nodeValue;
            var description = select('//Description/text()', doc)[i].nodeValue;
            var row = [{
                "toBottom": true,
                "cells": [
                // Note that the column Ids here are samples.  Adjust as required.
                {"columnId": 2461535086897028, "value": rowcounter, "strict": false},
                {"columnId": 6965134714267524, "value": identifier, "strict": false},
                {"columnId": 1335635180054404, "value": description, "strict": false},
                {"columnId": 7457715923511172, "value": revision, "strict": false},
                {"columnId": 1828216389298052, "value": updated, "strict": false},
                {"columnId": 7176240946800516, "value": 'Marker', "strict": false},
                ]
            }];
        writeRow(row); 
        sleep(); 
        }
    }
);

// DUMMY SLEEP FUNCTION
var sleep = function () {
  let now = Date.now(), end = now + 3000;
  while (now < end) { now = Date.now(); }
};

// Function to write row to sheet.
function writeRow(row) {
                    var options = {
                  sheetId: <insert your own sheet ID here>, //note real sheet id needed 
                  body: row
                  };
    return new Promise((resolve, reject) => {
        try {
            let obj = smartsheetClient.sheets.addRows(options);
            resolve(obj);
        } catch (err) {
            reject(err);
        };
    });
let myPromise = smartsheetClient.sheets.addRows(options);
myPromise.then(data => {
    console.log("Line Written :", data);
}).catch(err => {
    console.log(err);
});
}

  1. 测试.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--  June 2021  -->
<DOCUMENT>
    <ITEM>
        <Identifier>2021-91</Identifier>
        <Revision>5</Revision>
        <Updated>Oct-20</Updated>
        <Description>Item Description 1.</Description>
    </ITEM>
    <ITEM>
        <Identifier>2021-97</Identifier>
        <Revision>1</Revision>
        <Updated>Oct-20</Updated>
        <Description>Item description 2.</Description>
    </ITEM>
    <ITEM>
        <Identifier>2020-14</Identifier>
        <Revision>0</Revision>
        <Updated>Oct-20</Updated>
        <Description>Item description 3.</Description>
    </ITEM>
    <ITEM>
        <Identifier>2019-44</Identifier>
        <Revision>2</Revision>
        <Updated>Oct-20</Updated>
        <Description>Item description 4.</Description>
    </ITEM>
    <ITEM>
        <Identifier>2021-06</Identifier>
        <Revision>2</Revision>
        <Updated>Oct-20</Updated>
        <Description>Item description 5.</Description>
    </ITEM>
    <ITEM>
        <Identifier>2019-13</Identifier>
        <Revision>2</Revision>
        <Updated>Oct-20</Updated>
        <Description>Item description 6.</Description>
    </ITEM>
    <ITEM>
        <Identifier>2020-03</Identifier>
        <Revision>2</Revision>
        <Updated>Oct-20</Updated>
        <Description>Item description 7.</Description>
    </ITEM>
    <ITEM>
        <Identifier>2021-19</Identifier>
        <Revision>2</Revision>
        <Updated>Oct-20</Updated>
        <Description>Item description 8.</Description>
    </ITEM>
    <ITEM>
        <Identifier>2019-56</Identifier>
        <Revision>0</Revision>
        <Updated>Oct-20</Updated>
        <Description>Item description 9.</Description>
    </ITEM>
    <ITEM>
        <Identifier>2020-15</Identifier>
        <Revision>3</Revision>
        <Updated>Oct-20</Updated>
        <Description>Item description 10.</Description>
    </ITEM>
</DOCUMENT><?xml version="1.0" encoding="UTF-8" standalone="yes"?>

  1. 测试.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="DOCUMENT">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="ITEM">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Identifier" type="xs:unsignedShort" />
                            <xs:element name="Revision" type="xs:unsignedByte" />
                            <xs:element name="Updated" type="xs:string" />
                            <xs:element name="Description" type="xs:string" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

任何建议将不胜感激。

4

2 回答 2

0

问题


Promise 是具有自己独立上下文的异步 API。它有 3 个状态,分别是待处理、解决和拒绝。

当 Promise 被解决时,它会调用 .then(cb) ,如果它失败了,也就是拒绝,它会在内部调用 .catch(cb) 。

首先,您没有等待 Promise 完成,无论它被解决还是被拒绝。

您应该使用 .then() 和 .catch() 等待它完成。也许 async/await API 会更好地做到这一点。

解决方案


实现延迟功能的标准方法


const delay = ms => new Promise(resolve => setTimeout(() => resolve(), ms)

写行()


 function writeRow(row) {//Return your promise and let it be controlled outside of function
            var options = {
                sheetId: < insert your own sheet ID here > , //note real sheet id needed 
                body: row
            };
            return new Promise((resolve, reject) => {
                try {
                    let obj = smartsheetClient.sheets.addRows(options);
                    resolve(obj);
                } catch (err) {
                    reject(err);
                };
            });
}

runner :将您的逻辑包装到异步函数中以使用 await API。


(或者你可以使用传统的方式通过 .then()、.catch() 来控制 Promise)

async function runner(){
    ...your scripts...
    for (var i = 0; i < 10; i++) {
       ...
       await writeRow(row)
       await sleep(3000)//write row and wait for 3 seconds
       ...
    }
}


...your scripts...
}

runner()
于 2021-07-14T05:50:40.747 回答
0

你必须知道

  1. Smartsheet API 不支持同时调用给定令牌。
  2. Smartsheet API 可以通过单个调用插入/更新多行,例如通过单个调用插入/更新 100 行。

所以改变你的解决方案的结构:

  1. 阅读您的源代码并构建要插入/更新的智能表行列表。
  2. 每 100 行块拆分该行列表。
  3. 每 100 行插入/更新
于 2021-07-14T11:45:34.353 回答