将promise链中的值传递给后续处理程序

时间:2014-09-04 07:10:57

标签: javascript promise es6-promise

考虑以下代码:

function openSocket() { /* returns a promise for a socket  */ }
function sendMessage1(socket) { /* sends 1st message, returns a promise for a response */ }
function sendMessage2(socket) { /* sends 2nd message, returns a promise for a response */ }
function cleanup(socket) { /* closes the socket */ }

function updateUI() {}
function showError(error) {}

openSocket()
    .then(sendMessage1)
    .then(sendMessage2)
    .then(cleanup)
    .then(updateUI)
    .catch(showError);

请注意,sendMessage*()个函数都接受套接字作为参数。但只有第一个会得到这个,因为只有第一个会得到openSocket()的解析值。

我可以通过在外部作用域中使用变量来解决这个问题,即在解析后分配套接字,然后在sendMessage2()中使用它,但它看起来有点笨拙和肮脏。

另外,我知道我可以使用一些库支持,如this answer regarding Q中所述。

我正在寻找一种设计此代码的规范方法,其中:

  • 不需要外部范围内的任何变量
  • 不会依赖第三方承诺库(应基于ES6承诺)

有没有办法实现这一目标?或者更好的重构我的代码以使其更容易?

1 个答案:

答案 0 :(得分:2)

您可以在不使用第三方库和外部范围混乱的情况下执行此操作。简单地说,将参数传递给下一个承诺,例如

function openSocket() {
    return new Promise(function(resolved, failed) {
        if (Socket creation successful) {
            resolved(socket);
        } else {
            failed(error message);
        }
    });
}

function sendMessage1(socket) {
    // Actually send the message 1
    return new Promise(function(resolved, failed) {
        if (Message sent successfully) {
            resolved([socket, message]);
        } else {
            failed(error message);
        }
    });
}

function sendMessage2(parameters) {
    var socket = parameters[0], message = parameters[1];
    // Actually send the message 2
    return new Promise(function(resolved) {
        if (Message sent successfully) {
            resolved(socket);
        } else {
            failed(error message);
        }
    });
}

function closeSocket(socket) {}

然后像在问题中那样调用它们

openSocket()
    .then(sendMessage1)
    .then(sendMessage2)
    .then(closeSocket)
    .catch(function(err) {
        console.error("Failed with error", err);
    });