如何在一系列依赖函数中构造javascript回调?

时间:2016-09-08 11:34:04

标签: javascript callback

我只使用了简单的回调,即执行异步AJAX调用的函数,并在完成后回调。每当事情变得复杂时,我就使用了$ .Deferred()。问题是每次处理promises都是很多代码,我想知道如何正确使用回调。

这是我的例子。 (从secondary()返回时出现问题):

function primary()
{
    //call secondary with self as callback
    var data    = secondary("someStr", primary);
    if (data !== false) {
        //logic that uses data
    }
}

function secondary(str, callback)
{
    //call the third function. Since we need parameters
    //on the callback, we create anon function
    var returnFromThird = tertiary(function() {
        secondary(str, callback);
    });

    if (returnFromThird !== false) {
        //when we have data from third do someting....
        //but here lies the problem, how do i callback primary()?
        return returnFromThird + " " + str;
    } else {
        //third is not yet ready
        return false;
    }
}

var myVar3  = null;
function tertiary(callback)
{
    if (myVar3 === null) {
        //do async ajax call that sets myVar3 value
        var ajaxRequest = $.ajax({
            url: "/someUrl",
            type: "POST",
            data: {myData : "blabla"},
            async: true,
        });
        ajaxRequest.done(function(data) {
            myVar3  = data;
            //issue the call back, so secondary() can come get myVar3
            callback();
        });
        //we did not have the required data so we return false
        return false;
    } else {
        return myVar3;
    }
} 

//execute
primary();

以下是我通常使用JQuery Deferred处理问题的方法:

function primary()
{
    var promise = secondary(str);
    $.when(promise).then(
        function (data) {
            //logic that uses data
        }
    );
}

function secondary(str)
{
    var dfd     = $.Deferred();
    var promise = tertiary();
    $.when(promise).then(
        function (data) {
            dfd.resolve(data + " " + str);
        }
    );
    return dfd.promise();
}

var myVar3  = null;
function tertiary()
{
    var dfd     = $.Deferred();
    if (myVar3 === null) {
        var ajaxRequest = $.ajax({
            url: "/someUrl",
            type: "POST",
            data: {myData : "blabla"},
            async: true,
        });
        ajaxRequest.done(function(data) {
            myVar3  = data;
            dfd.resolve(myVar3);
        });

    } else {
        dfd.resolve(myVar3);
    }
    return dfd.promise();
}

primary();

1 个答案:

答案 0 :(得分:1)

如果您正在使用回调,则应始终调用回调,有时不是return值:

var myVar3 = null;
function tertiary(callback) {
    if (myVar3 === null) {
        //do async ajax call that sets myVar3 value
        $.post("/someUrl", {myData : "blabla"}).done(function(data) {
            myVar3  = data;
            callback(data); // just pass the data to the callback
        });
    } else {
        return callback(myVar3); // always call the callback with the data
    }
}

现在你的其他功能看起来像这样:

function primary() {
    secondary("someStr", function(data) {
        //logic that uses data
    });
}

function secondary(str, callback) {
    tertiary(function(returnFromThird) {
        callback(returnFromThird + " " + str);
    })
}

但你是对的,你应该使用承诺,它大大简化了这一点:

var myVarPromise = null;
function tertiary() {
    if (myVarPromise === null)
        myVarPromise = $.post("/someUrl", {myData : "blabla"});
    return myVarPromise;
}
function primary() {
    return secondary("someStr").then(function(data) {
        //logic that uses data
    });
}
function secondary(str) {
    return tertiary().then(function(returnFromThird) {
        return returnFromThird + " " + str;
    });
}