You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SuiteScript 2.0(NetSuite)中使用Promise.all()

SuiteScript 2.0 异步批量提交行项目实现方案

核心思路

把每个选中行的提交请求包装成独立的Promise,通过Promise.all()并行执行所有异步请求,等全部请求完成后统一汇总成功/失败结果并展示提示。

客户端脚本实现

/**
 * @NApiVersion 2.x
 * @NScriptType ClientScript
 */
define(['N/https', 'N/ui/message', 'N/currentRecord'], function(https, message, currentRecord) {
    function submitSelectedLines() {
        // 1. 收集选中的行项目数据
        var sublistId = 'custpage_line_items'; // 替换为你的子列表ID
        var sublist = currentRecord.get().getSublist({sublistId: sublistId});
        var selectedPromises = [];

        for (var i = 0; i < sublist.getLineCount(); i++) {
            var isChecked = sublist.getSublistValue({
                sublistId: sublistId,
                fieldId: 'custpage_select', // 替换为你的复选框字段ID
                line: i
            });

            if (isChecked) {
                var lineData = {
                    workOrderId: sublist.getSublistValue({sublistId: sublistId, fieldId: 'custpage_wo_id', line: i}),
                    itemId: sublist.getSublistValue({sublistId: sublistId, fieldId: 'custpage_item_id', line: i}),
                    // 按需添加其他行数据字段
                };

                // 2. 为每个选中行创建异步请求Promise
                var requestPromise = https.promise.post({
                    url: window.location.href, // 提交到当前Suitelet
                    body: JSON.stringify(lineData),
                    headers: {
                        'Content-Type': 'application/json'
                    }
                })
                .then(function(response) {
                    return {
                        success: true,
                        data: JSON.parse(response.body)
                    };
                })
                .catch(function(error) {
                    // 捕获错误并包装为结果对象,避免Promise.all直接终止
                    return {
                        success: false,
                        error: error.message || '提交失败'
                    };
                });

                selectedPromises.push(requestPromise);
            }
        }

        if (selectedPromises.length === 0) {
            message.create({
                title: '提示',
                message: '请至少选择一个行项目',
                type: message.Type.INFORMATION
            }).show();
            return;
        }

        // 3. 等待所有异步请求完成
        Promise.all(selectedPromises)
        .then(function(results) {
            var successCount = 0;
            var errorMessages = [];

            // 汇总结果
            results.forEach(function(result) {
                if (result.success) {
                    successCount++;
                } else {
                    errorMessages.push(result.error);
                }
            });

            // 展示最终提示
            var msg = `提交完成:成功${successCount}条,失败${errorMessages.length}条`;
            if (errorMessages.length > 0) {
                msg += '\n错误详情:\n' + errorMessages.join('\n');
            }

            message.create({
                title: '提交结果',
                message: msg,
                type: errorMessages.length > 0 ? message.Type.WARNING : message.Type.CONFIRMATION
            }).show();
        });
    }

    return {
        submitSelectedLines: submitSelectedLines // 绑定到提交按钮的点击事件
    };
});

Suitelet端处理逻辑

/**
 * @NApiVersion 2.x
 * @NScriptType Suitelet
 */
define(['N/record', 'N/log'], function(record, log) {
    function onRequest(context) {
        if (context.request.method === 'POST') {
            try {
                // 解析客户端传递的行数据
                var lineData = JSON.parse(context.request.body);
                var workOrderId = lineData.workOrderId;
                var itemId = lineData.itemId;

                // 1. 创建自定义记录
                var customRecord = record.create({
                    type: 'customrecord_your_record_type' // 替换为你的自定义记录类型ID
                });
                customRecord.setValue({fieldId: 'custrecord_wo_id', value: workOrderId});
                customRecord.setValue({fieldId: 'custrecord_item_id', value: itemId});
                // 设置其他必要字段
                var customRecordId = customRecord.save();

                // 2. 更新工单行
                var workOrder = record.load({type: record.Type.WORK_ORDER, id: workOrderId});
                // 根据实际业务逻辑找到对应行并更新
                var lineCount = workOrder.getLineCount({sublistId: 'item'});
                for (var i = 0; i < lineCount; i++) {
                    var lineItemId = workOrder.getSublistValue({sublistId: 'item', fieldId: 'item', line: i});
                    if (lineItemId == itemId) {
                        workOrder.setSublistValue({sublistId: 'item', fieldId: 'custcol_submitted', value: true, line: i});
                        break;
                    }
                }
                workOrder.save();

                // 返回成功响应
                context.response.write(JSON.stringify({
                    status: 'success',
                    recordId: customRecordId
                }));
            } catch (e) {
                log.error('行项目提交失败', e.message);
                // 返回错误响应
                context.response.setHeader({name: 'Content-Type', value: 'application/json'});
                context.response.setStatus({status: 500});
                context.response.write(JSON.stringify({error: e.message}));
            }
        } else {
            // GET请求渲染Suitelet页面(保留原有页面渲染逻辑)
            // ... 你的页面渲染代码
        }
    }

    return {
        onRequest: onRequest
    };
});

关键注意事项

  • 错误处理:每个Promise单独添加catch,将错误包装为结果对象,确保Promise.all()能拿到所有请求的结果,不会因单个请求失败直接终止。
  • 并发限制:NetSuite对并发请求有数量限制,若选中行过多,建议拆分批次处理(比如每10个一组),避免触发限流。
  • 数据安全:传递敏感数据时,确保HTTPS加密,必要时添加身份校验逻辑。

内容的提问来源于stack exchange,提问作者Nadav Julius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:10:40