如何在if语句中使用回调?

时间:2013-10-17 09:04:14

标签: jquery if-statement callback

你好,我有一个问题,我无法理解如何进一步在if语句中编写回调。我想要执行第一个if语句然后执行actionArray函数。在actionArray函数完成100%之后,他应该检查第二个if语句。还有他的功能。我该怎么称重呢?我想我的想法很糟糕。

function addFunction(fn){
 if(rowChanged && upOk){
     jQuery("#save_btn").prop('disabled', true);            
     formmodified = false;              
     actionArray(updateArray, "update", fn);    
 }
 if(rowChanged && saveOk){
    jQuery("#save_btn").prop('disabled', true);
    formmodified = false;
    actionArray(saveArray, "save", fn); 
 }
 fn();
}

2 个答案:

答案 0 :(得分:0)

不要太担心,回调逻辑真的是“逆转”,一开始理解它并不容易。

function addFunction(fn){
    if(rowChanged && saveOk){
        // We will need this second step...
        var org_fn = fn;
        fn = function() {
                 jQuery("#save_btn").prop('disabled', true);
                 formmodified = false;
                 actionArray(saveArray, "save", org_fn);
             };
    }
    if(rowChanged && upOk){
        // We need the first step
        var org_fn_2 = fn;
        fn = function() {
                 jQuery("#save_btn").prop('disabled', true);            
                 formmodified = false;              
                 actionArray(updateArray, "update", org_fn_2);
             };
    }
    setTimeout(fn, 0); // Schedule the call
}

这个想法是:调用程序为您提供了在完成所有操作时调用的函数。期望您的函数立即返回,而不是立即调用回调。因此,如果是空处理,它应该是

function addFunction(fn){
    setTimeout(fn, 0);
}

所以我们立即返回,并尽快调用完成回调。

如果要进行异步处理,我们将替换传递的回调替换另一个要求进行处理的回调,并在完成时调用原始回调。这是Javascript作用域规则有点烦人的地方,我们被迫声明一个不同的变量org_fn来存储原始回调并将传递的回调包装在将要进行处理的函数中。

如果有可能有两个步骤,那么我们需要使用不同的org_fn_2变量再次进行此换行。

包装也需要以相反的顺序进行,因为我们希望在完成第一步之后完成第二步(如果存在第一步)。

答案 1 :(得分:0)

编辑,看起来我错过了问题中的细节......

因此,您要做的是异步执行串行操作。

这是可以重复使用的东西:

series([
    function(callback) {
        if ( rowChanged && upOk ) {
            jQuery('#save_btn').prop('disabled', true);
            formmodified = false;
            actionArray(updateArray, 'update', callback);
        } else {
            callback();
        }
    },
    function(callback) {
        if ( rowChanged && saveOk ){
            jQuery('#save_btn').prop('disabled', true);
            formmodified = false;
            actionArray(saveArray, 'save', callback); 
        } else {
            callback();
        }
    }
],fn);

function series(taskList,done) {
    var next = taskList.shift();
    if ( typeof next === 'function' ) {
        next(series.bind(this,taskList,done));
    } else if ( typeof done === 'function' ) {
        done();
    }
}

...这是一个模拟版本,全部拼写出来(超时表示异步任务):

// first create the task list
var tasks = [
    function one(callback) { // this is a "medium" difficulty task
        console.log('one',new Date()); // so you can see some output
        setTimeout(callback,1000); // return callback after 1 second (async)
    },
    function two(callback) { // this is a "hard" difficulty task
        console.log('two',new Date()); // more output
        if ( true ) { // after some initial logic
            setTimeout(function() { // and then an async task for 500ms
                if ( true ) { // and more logic later
                    callback(); // issue the callback
                }
            },500);
        }
    },
    function three(callback) { // this is an easy task
        console.log('three',new Date());
        callback(); // return callback right away
    }
];

// `series` will handle moving the task list along
function series(taskList,done) {
    var next = taskList.shift(); // get the next function to call
    if ( typeof next === 'function' ) { // if there is one, and it is a function
        next(series.bind(this,taskList,done)); // execute it, and pass it the callback for the next task
    } else if ( typeof done === 'function' ) { // if there isn't another task, but there's a done function
        done(); // call the complete function, this is guaranteed to fire, if defined
    }
}
series(
    tasks.slice(0), // make a copy of tasks to save for later (if you want)
    function complete() { // complete will be called when the tasks have run out
        console.log('complete!',new Date());
    }
); 
//series(tasks); // alternatively, w/o the copy `.slice(0)` tasks will be depleted when it is done

OLD:

只需保持嵌套lambda:

function addFunction(fn) {
    if (rowChanged && upOk) {
        jQuery("#save_btn").prop('disabled', true);
        formmodified = false;
        actionArray(updateArray, "update", function() {
            if (rowChanged && saveOk) {
                jQuery("#save_btn").prop('disabled', true);
                formmodified = false;
                actionArray(saveArray, "save", fn);
            }
        });
    }
}

非常难看,但很典型,直到你开始真正组织你的代码和/或使用libs(例如async)。