1

您好我有一个问题,我无法理解如何在 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();
}
4

2 回答 2

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如果可能有两个步骤,那么我们需要使用不同的变量再次执行此包装。

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

于 2013-10-17T09:41:11.960 回答
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

老的:

只需继续嵌套 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);
            }
        });
    }
}

非常丑陋,但很典型,直到您开始真正组织代码和/或使用库(例如async)。

于 2013-10-17T09:48:03.667 回答