惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
Google DeepMind News
Google DeepMind News
V
V2EX
B
Blog RSS Feed
有赞技术团队
有赞技术团队
博客园 - Franky
美团技术团队
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
腾讯CDC
云风的 BLOG
云风的 BLOG
L
LangChain Blog
GbyAI
GbyAI
The Cloudflare Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Check Point Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Stack Overflow Blog
Stack Overflow Blog
博客园 - 【当耐特】
The Register - Security
The Register - Security
大猫的无限游戏
大猫的无限游戏
D
Docker
Vercel News
Vercel News
Blog — PlanetScale
Blog — PlanetScale
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 司徒正美
人人都是产品经理
人人都是产品经理
雷峰网
雷峰网
阮一峰的网络日志
阮一峰的网络日志
P
Proofpoint News Feed
N
Netflix TechBlog - Medium
博客园_首页
A
About on SuperTechFans
J
Java Code Geeks
量子位
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MongoDB | Blog
MongoDB | Blog
Recent Announcements
Recent Announcements
G
Google Developers Blog
小众软件
小众软件
博客园 - 叶小钗
WordPress大学
WordPress大学
博客园 - 聂微东
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Martin Fowler
Martin Fowler
S
SegmentFault 最新的问题
F
Full Disclosure
Jina AI
Jina AI
H
Help Net Security

博客园 - sonicit

后台数据缓存的一点心得 C# 使用 Newtonsoft.Json 对DataTable转换中文乱码问题的解决 Vue 数据双向绑定的误区 关于JS Pormise的认识 关于jqGrid中GridUnload方法的困惑 Javascript异步编程的4种方法 SQLServer 获得所有表结构(包括表名及字段) ACE代码编辑器,代码提示,添加自定义数据 利用闭包向post回调函数传参数 在seajs中使用require加载静态文件的问题 jqGrid标题行与第一行之间有很大空白的问题解决。 关于bootstrapValidator提交问题的解决 心得(一) 使用心得(一) MSSQL获得表的字段名称及其参数 Controller_Abstract的改造 QeePHP View视图的默认变量与新增变量 Delphi 的内存操作函数(5): 复制内存 Windows 7 安装VS2008 SP1 失败
再写Javascript闭包
sonicit · 2021-12-17 · via 博客园 - sonicit

     Javascript 闭包, 老生常谈。

     近期遇到问题时,在可编辑表格中键盘快速的上下移动,每次移动会触发change事件,而change事件中执行的是异步访问后台后填充行(且会有多次访问的情况发生,使用Promise数组同步执行)。

此时的现象为,表格中行数据不完整,有的有的没有。

     原来的代码如下:

const rowChangeTasks = []
// 原来的代码,单行逐行填充
arrayValue.forEach((value, idx) => {
    const changeSqls = changesql.split(';')
    changeSqls.forEach(cSQL => {
        const p = () => {
            return new Promise((resolve, reject) => {
                const _this = this
                this.selectedRow = table.tableFullData[theRowIndex + idx]
                this.selectedRow[columnName] = value
                const sql = this.replaceAllParams(cSQL)
                this.ExecCmd({ sql: sql, callName: '表格单元格change事件,执行存储过程', callMethod: 'tableCellDataChangeHandler' }).then(res => {
                    return this.getErrorData(res, 'subtable')
                }).then(res => {
                    if (res && res.length) {
                        const rowData = Object.assign({}, res[0])
                        if (Object.prototype.hasOwnProperty.call(rowData, _this.keyname)) {
                            delete rowData[_this.keyname]
                        }
                        // rowData[this.keyname] = `-${idx + theRowIndex}`
                        const currentColumnObject = {}
                        currentColumnObject[columnName] = value
                        Object.assign(table.tableFullData[theRowIndex + idx], currentColumnObject, rowData)
                        return table.cellDefaultValue(table.tableFullData[theRowIndex + idx], theRowIndex + idx)
                    } else {
                        return Promise.resolve()
                    }
                }).then(() => {
                    table.calcFormulasHandler(table.tableFullData[theRowIndex + idx], columnName) // 计算公式
                    resolve()
                }).catch(error => {
                    reject(error)
                })
            })
        }
        rowChangeTasks.push(p)
    })
    if (idx) {
        table.tableFullData[theRowIndex + idx][columnName] = value
    }
})
this.common.doPromiseArray(rowChangeTasks).then(() => {
    console.log('结束')
})

且后,我想到了用闭包的方式来处理,新的代码如下:

const rowChangeTasks = []
// 原来的代码,单行逐行填充
arrayValue.forEach((value, idx) => {
    const changeSqls = changesql.split(';')
    changeSqls.forEach(cSQL => {
        const p = ((currentRow, currentRowIndex) => {
            return new Promise((resolve, reject) => {
                const _this = this
                // this.selectedRow = table.tableFullData[theRowIndex + idx]
                currentRow[columnName] = value
                const sql = this.replaceAllParams(cSQL, { selectedRow: currentRow })
                this.ExecCmd({ sql: sql, callName: '表格单元格change事件,执行存储过程', callMethod: 'tableCellDataChangeHandler' }).then(res => {
                    return this.getErrorData(res, 'subtable')
                }).then(res => {
                    if (res && res.length) {
                        const rowData = Object.assign({}, res[0])
                        if (Object.prototype.hasOwnProperty.call(rowData, _this.keyname)) {
                            delete rowData[_this.keyname]
                        }
                        // rowData[this.keyname] = `-${idx + theRowIndex}`
                        const currentColumnObject = {}
                        currentColumnObject[columnName] = value
                        Object.assign(currentRow, currentColumnObject, rowData)
                        return table.cellDefaultValue(currentRow, currentRowIndex)
                    } else {
                        return Promise.resolve()
                    }
                }).then(() => {
                    table.calcFormulasHandler(currentRow, columnName) // 计算公式
                    resolve()
                }).catch(error => {
                    reject(error)
                })
            })
        })(table.tableFullData[theRowIndex + idx], theRowIndex + idx)
        rowChangeTasks.push(p)
    })
    if (idx) {
        table.tableFullData[theRowIndex + idx][columnName] = value
    }
})
this.common.doPromiseArray(rowChangeTasks).then(() => {
    console.log('结束')
})

用了闭包,有效解决了这个问题。