如何在上一次请求完成后对单个端点执行串行批量PUT请求
解决Lambda端点串行执行PUT请求的问题
这个场景太典型了——后端服务(比如你的Lambda)扛不住并发请求,咱们得把并行的Promise.all改成逐个串行执行,这里给你两种简单易维护的实现方式:
方法1:用async/await + for...of(最直观)
这种方式代码可读性最高,逻辑一目了然,就是循环遍历数组,每次等上一个请求完成再发下一个:
async function sendData(data: any) { type NewContact = { contact_type: number; contact_code: []; contact_type_desc: string; changed_by: string; }; console.log('Array: ', data); const headers = { "x-api-key": env['x-api-key'], }; const endpoint = env['contact_types'](studentId); // 存储所有请求的结果(可选) const results = []; for (const newContactType of data) { try { const response = await fetch(endpoint, { method: 'PUT', headers: headers, body: JSON.stringify(newContactType) }); console.log('Response: ', response); if (response.ok) { const result = await response.json(); results.push(result); } else { throw new Error(`Request failed with status ${response.status}`); } } catch (error) { console.log('Fetch operation problem: ', (error as Error).message); // 这里可以选择:是终止后续请求(直接throw error),还是继续执行? // throw error; // 取消注释就会终止 results.push(null); // 或者记录失败,继续执行 } } return results; // 返回所有请求结果 }
为什么这个能串行?
await会暂停当前函数的执行,直到fetch的Promise完成,所以下一次循环会等到上一个请求彻底结束才会触发。
方法2:用Array.reduce链式调用Promise(函数式风格)
如果你更喜欢函数式写法,可以用reduce把数组转成一串链式的Promise,前一个完成后再执行下一个:
function sendData(data: any) { type NewContact = { contact_type: number; contact_code: []; contact_type_desc: string; changed_by: string; }; console.log('Array: ', data); const headers = { "x-api-key": env['x-api-key'], }; const endpoint = env['contact_types'](studentId); // 用reduce构建串行Promise链 return data.reduce((prevPromise: Promise<any[]>, newContactType: NewContact) => { return prevPromise.then((results) => { return fetch(endpoint, { method: 'PUT', headers: headers, body: JSON.stringify(newContactType) }) .then((response) => { console.log('Response: ', response); if (response.ok) { return response.json().then(json => [...results, json]); } else { throw new Error(`Request failed with status ${response.status}`); } }) .catch((error) => { console.log('Fetch operation problem: ', error.message); // 同样,这里可以选择终止还是继续 // throw error; return [...results, null]; }); }); }, Promise.resolve([])); // 初始Promise,返回空数组 }
这个方法的逻辑:
reduce的初始值是一个已resolve的空数组Promise,每一步都会把当前请求的Promise链到前一个后面,确保顺序执行,最后返回所有结果的数组。
注意点
- 错误处理:根据你的业务需求决定,某个请求失败后是终止后续请求,还是继续执行。上面的代码里都给出了两种选择的注释。
- 性能:串行执行肯定比并行慢,但这是后端限制下的必要妥协。如果Lambda能承受少量并发(比如5个),也可以考虑分批串行(比如每次发5个,等一批完成再发下一批),不过你的需求是必须逐个执行,所以上面两种方法就够了。
内容的提问来源于stack exchange,提问作者Dennis
相关产品推荐
相关产品推荐

