如何在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
相关产品推荐
相关产品推荐

