【问题标题】:Jquery : control function flow with deferredJquery:具有延迟的控制功能流
【发布时间】:2012-05-29 19:09:43
【问题描述】:

抱歉,但我似乎在绕圈子。

过程相当简单

  1. SaveButtonClicked

  2. 调用函数执行离线数据库事务以更新记录

  3. 检查是否在线(/*使用 Ed Norton 示例进行此操作 */)

  4. 如果在线调用选择事务以获取所有更新的记录

  5. 选择加载成功结果到数组中

  6. 用数组调用webservice

到目前为止,我已经尝试使用 $.Deferred, dothis = defer.pipe(...), .queue [但这些似乎基于元素而不是功能完成] , 将函数放入数组中,

在测试中,控制台总是在“构建数组”之前写入“构建数组”

var arrvals = [];
var deferA , deferB;
function updatedb(params){
    db.transaction('update....',[params],updateOk,updateFail)
}
function updateOk(){
    deferA.resolve()
}
function updateFail(){
    deferA.reject()
}
function areweonline(){
    $.ajax(.....) 
}
function selectrows(){
    db.transaction('update....',[params],buildarray,selectFail)
}
function buildarray(transaction,results){
    console.log('building array')
    for(i=0;i<=results.rows.length;i++){
        var row = results.rows.item(i);
        var job = {};
        job.text = row["testtext"]
        arrvals.push(job);
    }
    deferB.resolve()
}
function selectFail(){
    deferB.reject();
}
function callwebservice(vals){
    $.ajax(....) /* this bit is working fine*/
}
function SaveButtonClicked(){
    deferA = $.Deferred(); 
    deferB = $.Deferred();
    $.when(deferA).then(
        console.log('update completed')
        $.when(deferB).then(function(){
            console.log('array built')
            callwebservice(arrvals)
        })
    )
}

那么最好的方法是什么? $.Deffered、队列、回调……黑魔法?

【问题讨论】:

    标签: jquery queue jquery-deferred deferred chain


    【解决方案1】:

    这样试试

    function updatedb(params) {
        var deferA     = $.Deferred(),
            updateOk   = function() { deferA.resolve(); },
            updateFail = function() { deferA.reject(); }
    
        db.transaction('update....',[params],updateOk,updateFail);
        return deferA.promise();
    }
    
    
    function selectrows() {
    
        var arrvals = [];
    
        var deferB     = $.Deferred(),
            buildarray = function (transaction, results) {
                console.log('building array')
                for(i = 0; i <= results.rows.length; i++){
                    var row = results.rows.item(i);
                    var job = {};
                    job.text = row["testtext"]
                    arrvals.push();
                }
                deferB.resolve(arrvals);
            },
            selectFail = function() {
                deferB.reject();
            };
    
        db.transaction('update....',[params],buildarray,selectFail);
        return deferB.promise();
    }
    
    
    function callwebservice(vals) { $.ajax(....) /* this bit is working fine*/ }
    
    
    function SaveButtonClicked(){
    
        $.when(updatedb('your params here')).then(
            console.log('update completed')
            $.when(selectrows()).then(function(arr){
                console.log('array built');
                callwebservice(arr)
            })
        )
    }
    

    一些想法

    • selectrows 函数上有一个空的push()(我认为这不是你想要的,因为arrvals 是空的);
    • 我重构了您的代码以使用更少的全局变量/函数:延迟对象现在在返回承诺的函数中声明;
    • arrvals 现在定义在selectrows() 函数中,你可以在解决延迟任务时传递它;
    • areweonline() 函数已从我的示例中删除(因为您没有在 sn-p 中的任何地方使用它);
    • when() 现在正在寻找承诺(而不是延期)。

    注意:我没有尝试执行代码,但希望这能有所帮助

    【讨论】:

    • FWIW,没有必要在 deferA.resolve() - deferA.resolve 周围包裹一个函数,因为函数引用了一个对内部延迟对象的封闭引用。
    • 感谢@F.Calderan 的指导,非常感谢您的帮助,很抱歉错过了 push(job) 位(快速输入),areweonline 只是调用 selectrows 之前的检查(没有必要调用如果不在线,则选择行)。再次欢呼
    猜你喜欢
    • 2012-11-05
    • 2011-05-02
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多