簡體   English   中英

如何在不創建閉包的情況下繼承承諾鏈中的數據?

[英]How to inherit data in a chain of promises without creating a closure?

這是一個工作代碼示例:

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”以獲取有關位置的其他信息。 最后,我將位置特定信息與初始位置信息結合在一起。

我對上面的代碼不滿意的是它不是平坦的。 如果特定於位置的查詢將需要其他異步信息,而其子查詢甚至將需要更多其他異步信息,則代碼將變成回調地獄。

我想將代碼轉換為平面結構,例如(偽代碼)

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;
    });

如果在request()之后執行bind({}),則鏈中的函數將具有this對象,可用於存儲事物。

例:

Promise.resolve('A').bind({}).then(function(value){
    this.value = value;
    return 5;
}).then(function(number) {
    this.number = number;
}).then(function() {
    console.log(this);
})

輸出:

{ value: 'A', number: 5 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM