1

我在这里阅读了很多线程,并试图了解回调和延迟等。基本上是它的历史。

我的意思是假设我有 3 个功能

function Primary() {console.log('Primary')};
function Secondary() {console.log('Secondary')};
function College() {console.log('College')};
  • 我将如何称呼他们一个接一个?
  • 在 Deferred 引入之前,回调是唯一的方法吗?
  • Callbacks 的哪些缺点会促使我将代码移动到使用 Deferred 对象?

对我来说,我理解的是 deferred 是一种管理多个回调的简单方法。但我无法将它与一个例子联系起来,以便我可以比较和决定。如何以及为什么容易?

Promises 是如何出现的?

我忘记添加的一个重要部分,Richard 猜对了,我需要下一个函数的第一个函数的结果

4

1 回答 1

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 作为其回调传递给内部执行。承诺有助于缓解的问题是,对于深度回调链,你会得到这个嵌套回调的侧面圣诞树,它丑陋且难以阅读。您可以使用 Promise 对其进行一些重组,如下所示:

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 对象,用于链接下一个函数调用,我们立即在函数中解析它们,因为这里没有异步逻辑。你可以在这里阅读一篇关于 Promise 的非常好的文章。

编辑:再丑一点,只是为了证明侧身的树看起来更多,给你,阿切尔: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 传递给它时,它会以一种很好的通用方式自动作为 receivedVal 传递到下一个回调中。

于 2013-11-12T15:28:33.280 回答