再写Javascript闭包

     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('结束')
})

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

原文地址:https://www.cnblogs.com/sonicit/p/15704011.html