按顺序执行回调

时间:2013-11-12 15:06:28

标签: jquery

我在这里读了很多帖子,并试图理解回调和推迟等等。基本上就是它的历史。

我的意思是让我说我​​有3个功能

function Primary() {console.log('Primary')};
function Secondary() {console.log('Secondary')};
function College() {console.log('College')};
  • 我将如何一个接一个地打电话给他们?
  • 回调是唯一的方式 在Deferred推出之前这样做?
  • 回调的哪些缺点会促使我将代码移动到使用Deferred 对象?

据我所知,延迟是一种管理多个回调的简单方法。但是我无法将它与一个例子联系起来,以便我可以比较和决定。如何以及为何容易?

Promise如何进入画面?

我忘了补充一点,理查德猜对了,我需要下一个第一个函数的结果

1 个答案:

答案 0 :(得分:1)

如果我正确地阅读了这个,你就会问如何链接这些函数,使它们作为对方的回调执行,然后将它移动到延迟/承诺模型的目的是什么?要将这些称为回调,首先必须改变编写这些函数的方式,以便它们各自执行回调:

function Primary(callback) {
    console.log('Primary');
    if (typeof callback === 'function') {
        callback();
    }
}
function Secondary(callback) {
    console.log('Secondary');
    if (typeof callback === 'function') {
        callback();
    }
};
function College(callback) {
    console.log('College');
    if (typeof callback === 'function') {
        callback();
    }
};

现在你可以通过将它们作为回调传递给1个函数调用来调用其中的每一个,如下所示:

Primary(function () {
    Secondary(College);
});

您正在调用Primary函数,并传递匿名函数回调以在Primary中执行。该函数将调用Secondary,并将College作为其内部执行的回调传递。这个问题有助于缓解这个问题,对于深度回调链,你会得到这个嵌套回调的横向圣诞树,它很丑陋且难以阅读。您可以使用promises重构一些,如下所示:

function Primary() {
    console.log('Primary');
    return $.Deferred().resolve().promise();
};
function Secondary() {
    console.log('Secondary');
    return $.Deferred().resolve().promise();
};
function College() {
    console.log('College');
    return $.Deferred().resolve().promise();
};

现在你可以像这样调用你的功能链:

Primary()
    .then(Secondary)
    .then(College);

现在你有一个很好的执行链,它很容易阅读,每一个都会在前一个完成后立即执行。我们从每个函数返回一个promise对象,用于链接下一个函数调用,我们立即在函数中解析它们,因为这里没有异步逻辑。你可以阅读一篇关于承诺的好文章here

编辑:为了让它更丑陋,只是为了证明侧身树看起来更多,你走了,Archer:D

Primary(function () {
    Secondary(function () {
        College();
    });
});

对于如何使用传统回调数学方法将一个值传递给下一个的示例,对于user2983762,这是该实现的一个示例。注意:此实现特定于列出的用例。对于具有可能接收前一个函数调用值的可选回调的函数的任意嵌套,使用此模型会变得更加困难,因为函数可能返回函数,因此很难判断该函数是作为回调还是值接收的在任何通用点:

function Primary(callback) {
    var returnVal = true;
    console.log('Primary');
    if (typeof callback === 'function') {
        callback(returnVal);
    }
}
function Secondary(val, callback) {
    var returnVal = false;
    console.log('Secondary');
    if (typeof callback === 'function') {
        callback(returnVal);
    }
};
function College(val) {
    console.log('College');
    if (typeof callback === 'function') {
        callback();
    }
};
Primary(function (primaryVal) {
    Secondary(primaryVal, function (secondaryVal) {
        College(secondaryVal);
    });
});

这将调用Primary,将我们的匿名函数作为回调触发,它接收primaryVal,然后调用Secondary,传递另一个匿名函数,它接收secondaryVal,然后调用College,将secondaryVal传递给它。在延迟对象模型下,这变得更容易处理,以及抽象,如下:

function Primary(receivedVal) {
    var returnVal = true;
    console.log('Primary');
    return $.Deferred().resolve(returnVal).promise();
};
function Secondary(receivedVal) {
    var returnVal = false;
    console.log('Secondary');
    return $.Deferred().resolve(returnVal).promise();
};
function College(receivedVal) {
    var returnVal = {};
    console.log('College');
    return $.Deferred().resolve(returnVal).promise();
};

在这种情况下,我们根本不需要改变我们的执行链。每次我们解析其中一个函数并将returnVal传递给它时,它会以一种漂亮的通用方式自动传递给下一个回调为receiveVal。