Node.js中拆分fetch Promise代码至多文件后返回[Function]问题排查
问题分析与解决
你遇到的问题核心是在Promise链里意外返回了一个函数,而不是你期望的过滤后的数据。咱们一步步拆解来看:
错误根源:返回了函数而非处理结果
先看你单独文件里的这段代码:
module.exports = function(url, branch) { return fetch(url) .then( res => res.json()) .then( data => data => Object.keys(data.values).filter( value => value.source.branch === branch)) .catch( err => console.log(err)) };
注意第二个.then里的写法:data => data => Object.keys(...),这相当于你接收data后,返回了一个新的箭头函数(data => ...),而不是直接执行过滤操作并返回结果。所以当你在调用文件里用.then(desc => console.log(desc))时,desc就是这个未执行的函数,自然输出[Function]。
修正后的代码
把第二个.then里的嵌套箭头函数去掉,直接处理数据并返回结果:
module.exports = function(url, branch) { return fetch(url) .then(res => res.json()) // 直接处理data,返回过滤后的数组 .then(data => { // Object.keys返回的是键名,需要用键名取对应的value return Object.keys(data.values) .filter(key => data.values[key].source.branch === branch) .map(key => data.values[key]); // 若需要具体对象而非键名,加上map转换 }) .catch(err => { console.log(err); // catch仅打印会让Promise链返回undefined,建议重新抛出错误供调用方处理 throw err; }); };
关于单文件嵌套写法的优化
你单文件里用了嵌套的.then(res.json().then(...)),虽然能工作,但Promise的设计初衷是用链式调用避免回调地狱,推荐改成更清晰的链式写法:
fetch(`https://api.bitbucket.org/2.0/repositories/${circle_project_username}/${circle_project_reponame}/pullrequests`, { headers: {Authorization: auth} }) .then(res => res.json()) .then(data => { const targetPr = Object.keys(data.values) .map(key => data.values[key]) .find(item => item.source.branch.name === branch); if (targetPr) { console.log(targetPr.description); } }) .catch(err => console.log(err));
用find代替forEach能更直接地定位到第一个符合条件的PR,逻辑更简洁。
关键概念回顾
Promise链式调用中,每个.then的返回值会作为下一个.then的输入:
- 返回普通值,下一个
.then接收该值 - 返回Promise,下一个
.then等待其完成后接收结果 - 返回函数,下一个
.then就会接收这个函数(也就是你遇到的情况)
所以一定要确保每个.then里返回的是你实际需要传递的数据,而非其他无关类型。
内容的提问来源于stack exchange,提问作者icicleking
相关产品推荐
相关产品推荐

