我如何 return 来自 then 子句的 Promises 数组

How can I return an array of Promises from a then clause

我看到了一个类似的问题 ,但它没有解决我的问题。我正在尝试每 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);
}

如果您不再为 .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() 也是异步的并且 returns 是一个承诺,那么您可能也想将它们挂接到承诺链中。


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

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