Node.js:如何在函数中使用Promise返回值实现地址校验?
问题分析与解决方案
咱们先把核心问题拆解清楚,再一步步修复:
1. 先解决checkAdd函数的返回值漏洞
你的checkAdd声明返回Promise<Object[]>,但内部的then回调里没有返回匹配结果allMatch,导致这个Promise最终会resolve成undefined——这是第一个关键问题,得先补上:
function checkAdd(address /* : string | void */) /* :Promise<Object[]> */ { // 先处理address为空的情况,避免调用toLowerCase报错 if (!address) { return Promise.resolve([]); } const convertToLowerCase = address.toLowerCase(); return Promise.resolve() .then(() => { // 必须return匹配数组,让Promise的resolve值是这个结果 return addressesAsJson.filter((record) => record.address === convertToLowerCase); }); }
2. 异步操作不能同步处理
checkAdd返回的是Promise对象,你直接用var results = checkAdd(address)拿到的是Promise实例,不是实际的数组结果,所以results.length永远是undefined,自然走不进你期望的逻辑分支。
下面给两种常用的修复写法,选你顺手的就行:
写法一:用Promise链式调用处理异步
function saveNewAd(address /* :?string | void */, cb) /* :Promise<string> */ { return checkAdd(address) .then((results) => { // 现在results才是真正的匹配数组 if (results.length > 0) { // 先做参数校验,避免后续操作报错 if (!address) { throw new Error("Address cannot be empty"); } const separatedAddress = address.split(','); if (separatedAddress.length < 3) { throw new Error("Invalid address format: need at least 3 parts separated by commas"); } // 删掉原代码里重复调用的checkAddressAvailable(冗余操作) const firstAddLine = capitalFirstLetter(separatedAddress[0]); const secondAddLine = separatedAddress[1].toUpperCase(); const thirdAddLine = separatedAddress[2].toUpperCase(); const displayAddress = `${firstAddLine},${secondAddLine},${thirdAddLine}`; addressesAsJson.push({ "address": address.toLowerCase(), "display": displayAddress }); // 把文件写入包装成Promise,统一异步逻辑 return new Promise((resolve, reject) => { fs.writeFile(jsonListPath, JSON.stringify(addressesAsJson), (err) => { err ? reject(err) : resolve("New address is saved"); }); }); } else { // 这里根据你的需求抛出错误,让Promise状态正确 throw new Error("No matching address found, cannot save"); } }) .catch((err) => { console.log(err.message); throw err; // 传递错误,让调用者可以捕获处理 }); }
写法二:用async/await(更简洁易读)
async function saveNewAd(address /* :?string | void */, cb) /* :Promise<string> */ { try { const results = await checkAdd(address); if (results.length > 0) { // 参数校验不能少 if (!address) throw new Error("Address cannot be empty"); const separatedAddress = address.split(','); if (separatedAddress.length < 3) { throw new Error("Invalid address format: need at least 3 parts separated by commas"); } const firstAddLine = capitalFirstLetter(separatedAddress[0]); const secondAddLine = separatedAddress[1].toUpperCase(); const thirdAddLine = separatedAddress[2].toUpperCase(); const displayAddress = `${firstAddLine},${secondAddLine},${thirdAddLine}`; addressesAsJson.push({ "address": address.toLowerCase(), "display": displayAddress }); // 等待文件写入完成 await new Promise((resolve, reject) => { fs.writeFile(jsonListPath, JSON.stringify(addressesAsJson), (err) => { err ? reject(err) : resolve(); }); }); return "New address is saved"; } else { throw new Error("No matching address found, cannot save"); } } catch (err) { console.log(err.message); throw err; } }
额外补全提示
如果你的capitalFirstLetter还没实现,这里给个通用版本:
function capitalFirstLetter(str) { if (!str) return str; return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); }
内容的提问来源于stack exchange,提问作者venura
相关产品推荐
相关产品推荐

