javascript - 如何在不创建闭包的情况下继承 promise 链中的数据?

标签 javascript promise bluebird

这是一个工作代码的示例:

request('http://foo.com/')
    // Collect list of locations.
    .then(function (response) {
        let $ = response.data,
            locations = [];

        $('a[href^="/venues/"]').each(function () {
            locations.push({
                name: $(this).text(),
                url: 'http://foo.com/' + $(this).attr('href')
            });
        });

        return locations;
    })
    // Retrieve additional information about locations.
    .map((location) => {
        return request(location.url)
            .then((response) => {
                // Combine location specific information with the initial location information.
                response;
                location;
            });
    }, {
        concurrency: 5
    });

在上面的示例中,我向“foo.com”发出请求,获取位置列表,然后使用位置数据查询“foo.com”以获取有关该位置的其他信息。最后,我将位置特定信息与初始位置信息结合起来。

我不喜欢上面的代码的是它不平坦。如果特定于位置的查询需要额外的异步信息,并且它的子查询需要更多额外的异步信息,则代码将变成回调 hell 。

我想将代码变成扁平结构,例如(伪代码)

request('http://foo.com/')
    // Collect list of locations.
    .then(function (response) {
        let $ = response.data,
            locations = [];

        $('a[href^="/venues/"]').each(function () {
            locations.push({
                name: $(this).text(),
                url: 'http://foo.com/' + $(this).attr('href')
            });
        });

        return locations;
    })
    // Retrieve additional information about locations.
    .map((location) => {
        return request(location.url);
    }, {
        concurrency: 5
    })
    // Filter list of responses.
    .filter((response) => {
        return response.incomingMessage.statusCode === 200;
    })
    // Combine location specific information with the initial location information.
    .map((response) => {
        // How to access "location" and "response"?
    });

实现这一目标的最佳方法是什么?

最佳答案

我能想到的唯一方法是通过增强请求的响应来获取有关位置的附加数据,例如

.map((location) => {
    return request('http://foo.com/' + location.nid)
        .then((response) => {
            return {
                location: location,
                response: response
            };
        });
}, {
    concurrency: 5
})

这样整个 Promise 链或多或少保持平坦。

request('http://foo.com/')
    // Collect list of locations.
    .then(function (response) {
        let $ = response.data,
            locations = [];

        $('a[href^="/venues/"]').each(function () {
            locations.push({
                nid: $(this).attr('href'),
                name: $(this).text(),
                url: 'http://foo.com/' + $(this).attr('href')
            });
        });

        return locations;
    })
    // Retrieve additional information about locations.
    .map((location) => {
        return request('http://foo.com/' + location.nid)
            .then((response) => {
                return {
                    location: location,
                    response: response
                };
            });
    }, {
        concurrency: 5
    })
    // Filter list of responses.
    .filter((response) => {
        return response.response.incomingMessage.statusCode === 200;
    })
    .map((response) => {
        // Combine location specific information with the initial location information.
        response.response;
        response.location;
    });

关于javascript - 如何在不创建闭包的情况下继承 promise 链中的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32789152/

相关文章:

javascript - Bluebird:如何绑定(bind)一个 promise ,以便我可以在 .catch 中自定义行为,然后允许错误继续级联?

javascript - React 在 props 改变时取消 Promise

node.js - Bluebird - 如何传播嵌套 promise 中的错误

node.js - promise node.js 类生成器方法

javascript - Javascript 中的平均值

javascript - 等待循环中调用的所有 promise 完成

javascript - 产生了一个不能被视为 promise 的值(value)

javascript - jQuery .fadeOut 没有正确淡出

javascript - 主干 - 声明模型内部获取的默认参数

javascript - 错误: cannot call methods on tabs prior to initialization; attempted to call method 'destroy'