1

I am trying to make multiple callout to Apex imperatively from a FOR loop. But strangely, only first 6 transaction are getting successful. Rest all are failing. There is no mention of any such limits of number of callout from LWC to Apex in Developer Document.

Reason to follow this approach is each callout will follow a new set of Apex limits.

import { LightningElement, api, wire, track } from 'lwc';
import insertRecords from '@salesforce/apex/FileUploaderXCtrl.insertRecords';

export default class FileUploadExample extends LightningElement {

    file;
    filename;
    filecontent;
    output = [];
    buttonVisible = false;
    position = 0;

    get acceptedFormats() {
        return ['.csv'];
    }

    uploadFiles(event) {
        console.log('Hey! No of Callouts: ----------->' + this.output.length);
        for (let index = 0; index < this.output.length; index++) {
            console.log('Making Callouts Now! Watch Out --------');
            insertRecords({ jsonObjInput: this.output[index] })
            .then(() => { console.log('*******\n\nHurray! Its Working....\n\n********'); })
            .catch((error) => { console.log('Go Home...'); });
            
        }
    }

    handleUploadFinished(event) {
        if (event.target.files.length > 0) {
            this.filename = event.target.files[0].name;
            this.file = event.target.files[0];
            var reader = new FileReader();
            var jsonObj = [];
            reader.readAsText(this.file, "UTF-8");
            reader.onload = (evt) => {
                console.log('File Name: ----------->' + this.filename);
                this.filecontent = evt.target.result;
                let rows = this.filecontent.split('\n');
                let header = rows[0].split(',');
                rows.shift();
                console.log('Header: ----------->' + header);
                rows.forEach(element => {
                    let data = element.split(',');
                    let obj = {};
                    for (let index = 0; index < header.length; index++) {
                        obj[header[index].trim()] = data[index].trim();
                    }
                    jsonObj.push(obj);
                });
                let result = new Array(Math.ceil(jsonObj.length / 10000)).fill().map(_ => jsonObj.splice(0, 10000));
                result.forEach(element => {
                    this.output.push(JSON.stringify(element));
                });
                console.log('Apex Input Parameter: ----------->' + this.output);
                console.log('No of Callouts: ----------->' + this.output.length);
            }
            reader.onloadend = (evt) => {
                this.buttonVisible = true;
            }
            reader.onerror = (evt) => {
                if (evt.target.error.name == "NotReadableError") {
                    console.log('An Error Occured Reading this File!!');
                    alert('An Error Occured Reading this File!!');
                }
            }
        }
    }

}
4

1 回答 1

0

已经有一些关于 stackexchange 的好文章。这被称为 boxcarring 并且由于浏览器能够限制并行调用的数量,lwc 会进行 boxcarring。

https://salesforce.stackexchange.com/questions/263382/how-to-turn-boxcarring-off-for-lwc-imperative-apex-method-calls?atw=1

https://salesforce.stackexchange.com/questions/293025/boxcaring-is-removed-from-lwc-components

您应该查看它们以了解为什么 salesforce 在 lwc 中进行 boxcarring。

简而言之,您可以选择与 promises 异步以避免这些,或者其他解决方法是 setTimeout。

这两种方法都不会提供出色的用户体验,相反,您应该探索其他替代方法来实现这一点,包括以下内容

  • 使用 Bulk API v2.0 进行所有数据操作
  • 在 Heroku 之类的东西上构建 UI 界面并使用 python 或 Node 来进行处理,而不是使用 apex 来执行资源密集型工作。
于 2020-08-24T19:07:41.057 回答