You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Promise内循环修改对象属性后resolve返回值未更新问题

问题描述

在Promise逻辑中通过循环为多个对象属性赋值时,执行函数并调用.then(() => console.log(r))打印结果,返回的r没有被修改为预期的赋值结果。

原实现代码
function assignSentenceImageDescription () {
    return new Promise((resolve, reject) =>
    {
        assigningWordsPartOFSpeech().then((r) => {

                JSON.parse(r).sentences.forEach((sentence) => {
                        let adjectiveBeforeNoun = [];
                        let sentenceImageDescription = [];
                        sentence.words.forEach((wordInSentence) => {
                            try {
                                if (wordInSentence.partOfSpeech[0].wordtype === "n.") {
                                    let imageDescription = adjectiveBeforeNoun.join('') + wordInSentence.partOfSpeech[0].word;
                                    sentenceImageDescription.push(imageDescription)
                                    adjectiveBeforeNoun = [];
                                } else if (wordInSentence.partOfSpeech[0].wordtype === "superl.") {
                                    adjectiveBeforeNoun.push(wordInSentence.partOfSpeech[0].word + " ")
                                }
                            } catch (e) {
                                console.log("===NOT IN DICTIONARY===")
                            }
                        })
                        sentence.imageDescription = sentenceImageDescription;
                    }
                )
                resolve(r);
            }
        );
    }
    );
}
问题根因
  • 核心错误:JSON.parse(r)每次执行都会生成一个全新的独立JavaScript对象,遍历、赋值操作都是在这个临时生成、没有被任何变量保存的对象上执行的,操作完成后临时对象会被直接回收,修改根本不会同步到原始的r值上。
  • 冗余写法:外层额外包了一层new Promise,属于Promise嵌套反模式,没有实际意义还容易引入逻辑错误。
  • 最后resolve(r)传递的还是原始的、未做任何修改的r字符串,打印结果自然看不到新增的imageDescription属性。
修复后代码
function assignSentenceImageDescription () {
    return assigningWordsPartOFSpeech().then((r) => {
        // 先把JSON解析结果存到变量,所有修改都在这个对象上操作
        const parsedData = JSON.parse(r);
        parsedData.sentences.forEach((sentence) => {
            let adjectiveBeforeNoun = [];
            let sentenceImageDescription = [];
            sentence.words.forEach((wordInSentence) => {
                try {
                    if (wordInSentence.partOfSpeech[0].wordtype === "n.") {
                        let imageDescription = adjectiveBeforeNoun.join('') + wordInSentence.partOfSpeech[0].word;
                        sentenceImageDescription.push(imageDescription)
                        adjectiveBeforeNoun = [];
                    } else if (wordInSentence.partOfSpeech[0].wordtype === "superl.") {
                        adjectiveBeforeNoun.push(wordInSentence.partOfSpeech[0].word + " ")
                    }
                } catch (e) {
                    console.log("===NOT IN DICTIONARY===")
                }
            })
            sentence.imageDescription = sentenceImageDescription;
        })
        // 如果后续需要JSON字符串就返回JSON.stringify(parsedData),需要对象直接返回parsedData即可
        return parsedData;
    });
}
修复要点
  • 把JSON解析的结果存入固定变量,所有属性修改操作都针对这个持久引用的对象执行,避免修改临时对象导致修改丢失
  • 移除多余的外层Promise包装,直接返回Promise链的结果,简化逻辑层级
  • 最终返回的是已经完成属性赋值的完整数据,而非原始未修改的入参r

内容的提问来源于stack exchange,提问作者Xavi Font

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 22:40:50