如何从then子句返回一个Promises数组

时间:2016-11-03 06:10:18

标签: promise es6-promise

我看到一个类似的问题here并没有解决我的问题。我试图每10个小时运行一个cron作业,让我先获得类别,然后根据类别,我找到每个类别的信息。如何简化以下承诺。我不使用Bluebird或Q,这是本机JS的承诺。老实说,下面的代码看起来像Promise应该避免的回调地狱,任何建议

flipkart.getAllOffers = function () {
    interval(43200, () => {
        flipkart.findAllCategories()
            .then((categories) => {
                flipkart.save('flipkart_categories.json', categories)
                if (categories) {
                    for (let item of categories) {
                        flipkart.findAllForCategory(item.category, item.top)
                            .then((items) => {
                                flipkart.save('flipkart_top_' + item.category + '.json', items)
                            }).catch((error) => {
                                console.log(error)
                            })
                    }
                }
            })
            .catch((error) => {
                console.log(error)
            })
    })
}

function interval(seconds, callback) {
    callback();
    return setInterval(callback, seconds * 1000);
}

1 个答案:

答案 0 :(得分:1)

如果您仅针对.then()停止使用额外级别的缩进,那么您的结构非常简单。

包含的一个.then()处理程序 一个if()声明 包含for循环 包含另一个异步操作

在此修改版本中,缩进的一半来自您的iffor,这与承诺无关。其余对我来说似乎很合乎逻辑,并且完全不像回调地狱。这是实现你展示的逻辑所需要的。

flipkart.getAllOffers = function () {
    interval(43200, () => {
        flipkart.findAllCategories().then((categories) => {
            flipkart.save('flipkart_categories.json', categories)
            if (categories) {
                for (let item of categories) {
                    flipkart.findAllForCategory(item.category, item.top).then((items) => {
                        flipkart.save('flipkart_top_' + item.category + '.json', items)
                    }).catch((error) => {
                        console.log(error)
                        throw error;     // don't eat error, rethrow it after logging
                    });
                }
            }
        }).catch((error) => {
            console.log(error)
        })
    })
}

如果flipkart.save()也是异步并返回一个promise,那么你可能也希望将它们挂钩到promise链中。

您总是可以创建一个可以改善外观的辅助函数,如下所示:

flipkart.getAllOffers = function () {
    interval(43200, () => {
        flipkart.findAllCategories().then(iterateCategories).catch((error) => {
            console.log(error);
        })
    })
}

function iterateCategories(categories) {
    flipkart.save('flipkart_categories.json', categories);
    if (categories) {
        for (let item of categories) {
            flipkart.findAllForCategory(item.category, item.top).then((items) => {
                flipkart.save('flipkart_top_' + item.category + '.json', items);
            }).catch((error) => {
                console.log(error);
            });
        }
    }    
}

如果您正在尝试收集所有结果(标题所暗示的内容,但您的问题实际上没有提及),那么您可以这样做:

flipkart.getAllOffers = function () {
    interval(43200, () => {
        flipkart.findAllCategories().then(iterateCategories).then((results) => {
            // all results here
        }).catch((error) => {
            console.log(error);
        });
    })
}

function iterateCategories(categories) {
    flipkart.save('flipkart_categories.json', categories);
    let promises = [];
    if (categories) {
        for (let item of categories) {
            let p = flipkart.findAllForCategory(item.category, item.top).then((items) => {
                flipkart.save('flipkart_top_' + item.category + '.json', items);
            }).catch((error) => {
                console.log(error);
            });
            promises.push(p);
        }
    }
    // return promise here that collects all the other promises
    return Promise.all(promises);
}