Promise映射数组结果不持久化问题排查求助
问题分析与解决方案
你的问题核心在于没有等待decorateNode返回的Promise全部完成就提前返回了myObj,导致最终拿到的decorators还是空数组。
咱们来拆解一下问题本质:
- 在第二个
.then回调里,你用data.map遍历节点并调用decorateNode,但decorateNode是异步操作(返回Promise),而map本身是同步执行的——它只会批量创建所有Promise,却不会等待这些Promise的then回调执行完毕。 - 所以你在
map之后立刻打印myObj.decorators时,所有decorateNode的异步请求还没完成,数组自然是空的;而你在then回调里的debugger能看到数组有值,是因为到那个断点时,对应的异步请求已经完成了。
修复后的代码示例
把map生成的所有Promise收集起来,用Promise.all等待它们全部完成后再返回myObj,这样就能保证拿到完整的decorators数组:
function formatMyObject( arrayOfIds ) { // 初始化对象 var myObj = { decorators: [], nodes: [] } // 映射Promise reconciliate()并将结果推入数组 return reconciliateNode(arrayOfIds) .then( data => { data.map( node => { // 获取结果并填充myObj.nodes myObj.nodes.push( { ...node } ) // 这里根据你的实际需求拷贝节点属性 }) return myObj }) .then( myObj => { // 收集所有decorateNode的异步Promise const decorationPromises = myObj.nodes.map( node => decorateNode(node.source) .then( decoration => { const decorationData = decoration[node.source] myObj.decorators.push( { ...decorationData } ) // 填充装饰器数据 }) ) // 等待所有异步装饰操作完成后,再返回最终的myObj return Promise.all(decorationPromises).then(() => myObj) }) // 后续可以继续链式处理最终结果 .then( finalObj => { console.log('最终的decorators数组:', finalObj.decorators) // 这里能看到完整数据 return finalObj }) }
串行执行的优化方案(如果需要)
如果你明确需要串行执行这些decorateNode请求(而不是并行),可以用Array.reduce来依次执行Promise,保证前一个请求完成后再执行下一个:
// 替换上面的decorationPromises部分 return myObj.nodes.reduce((prevPromise, node) => { return prevPromise.then(() => { return decorateNode(node.source) .then(decoration => { const decorationData = decoration[node.source] myObj.decorators.push({ ...decorationData }) }) }) }, Promise.resolve()) .then(() => myObj)
这样就能严格按照节点顺序,逐个完成装饰操作后再返回结果。
内容的提问来源于stack exchange,提问作者user305883
相关产品推荐
相关产品推荐

