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

如何让Backbone.js克隆操作等待服务器完成后再执行?

解决快速点击克隆书籍导致rowOrderNumber混乱的问题

你的问题核心是异步请求并发执行:多个克隆请求同时发起后,服务器生成rowOrderNumber时可能基于同一时刻的最大值计算,导致顺序混乱或重复。可以通过前端控制请求串行执行,让每个克隆操作等待前一个完成后再进行,具体实现有两种方式:

方式一:阻止重复点击(简单直接)

在视图中维护一个状态标志,标记当前是否有克隆操作正在进行,同时禁用按钮避免用户重复点击:

// 在视图的initialize方法中初始化状态
initialize: function() {
    this.isCloning = false;
},

clonebook: function () {
    var self = this;
    // 如果正在克隆,直接返回
    if (this.isCloning) return;
    
    this.isCloning = true;
    // 禁用copy按钮,视觉上提示用户
    this.$el.find('.copy-btn').prop('disabled', true);
    
    this.book.clone().then((r) => {
        self.model.collection.add(r);
    }).finally(() => {
        // 无论请求成功或失败,都重置状态和按钮
        self.isCloning = false;
        self.$el.find('.copy-btn').prop('disabled', false);
    });
},

方式二:任务队列(处理多次点击的排队需求)

如果需要支持用户多次点击,让所有克隆请求按顺序依次执行,可以用队列存储任务,逐个处理:

initialize: function() {
    this.cloneQueue = [];
    this.isCloning = false;
},

clonebook: function () {
    var self = this;
    // 将克隆任务加入队列
    this.cloneQueue.push(() => {
        return self.book.clone().then((r) => {
            self.model.collection.add(r);
        });
    });
    
    // 如果当前没有执行中的任务,启动队列处理
    if (!this.isCloning) {
        this.processCloneQueue();
    }
},

processCloneQueue: function() {
    var self = this;
    // 队列空了就结束
    if (this.cloneQueue.length === 0) {
        this.isCloning = false;
        this.$el.find('.copy-btn').prop('disabled', false);
        return;
    }
    
    this.isCloning = true;
    this.$el.find('.copy-btn').prop('disabled', true);
    
    // 取出队列第一个任务执行
    const currentTask = this.cloneQueue.shift();
    currentTask().then(() => {
        // 递归处理下一个任务
        self.processCloneQueue();
    }).catch((err) => {
        // 处理错误,不影响后续任务执行
        console.error('克隆失败:', err);
        self.processCloneQueue();
    });
},

补充:后端原子性保障(可选)

为了彻底避免并发问题,建议后端生成rowOrderNumber时使用原子操作,比如在SQL Server中用事务结合MAX函数:

BEGIN TRANSACTION;
DECLARE @newOrder INT;
SELECT @newOrder = ISNULL(MAX(rowOrderNumber), 0) + 1 FROM book WHERE libraryId = @targetLibraryId;
INSERT INTO book (bookTitle, authorId, libraryId, rowOrderNumber)
VALUES (@title, @authorId, @targetLibraryId, @newOrder);
COMMIT TRANSACTION;

这样即使前端有漏网的并发请求,后端也能保证rowOrderNumber的唯一性和顺序性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:50:34