简化嵌套承诺和循环

Simplifying nested promises and loops

本文关键字:循环 承诺 嵌套      更新时间:2023-09-26

我正在构建一个angular应用程序,我试图更好地理解关于承诺当我处理异步调用(如$http)时,我通常做的是将它们包装在一个服务中,然后在我的控制器中像这样调用它们:

...
function whatever(arguments) {
    dataService.getUser(arguments)
        .then(onUserComplete)
        .then(dataService.getExtra)
        .then(onExtraComplete)
        .catch(onError);
    function onUserComplete(user) {
        //do something with user
        ...
        // return user id (because we are
        // supposing that getExtra is
        // requiring an id as argument)
        return user.id;
    }
    function onExtraComplete(extra) {
        // do something with extra
        // no need to return anything,
        // we are the last element of the
        // chain.
    }
    function onError(error) {
        console.log(error);
    }
}
...

这有助于我保持每个函数的可理解性和可维护性,易于阅读和一致…至少在我需要处理收款之前。假设我需要做与之前相同的事情,但不是只有一个用户,而是获得用户的整个集合(并且我仍然需要获得每个单个用户的额外数据)。我所做的是:

...
function whatever(arguments) {
    dataService.getUsers(arguments)
        .then(onUsersComplete)
        .catch(onError);
    function onUsersComplete(users) {
        users.forEach(function(user) {
            dataService.getExtra(user.id)
                .then(onExtraComplete)
                .catch(onError);
        });
    }
    ...
}
...

这是最好的,我可以获得尝试遵循我的编码风格?甚至有可能用一个承诺链来解决我的问题吗?由于

你可以使用Promise.all (Documentation)来等待一组承诺。

dataService.getUsers(arguments)
    .then(users => users.map(
        user => dataService.getExtra( user.id )
    ))
    .then( Promise.all )
    .then( user_extra => /* get array with user data as result */ )
    .catch( onError );

我们将用户映射到函数返回的Promise数组,然后使用Promise。所有的承诺都捆绑在一起。在下一个.then()中,将加载所有用户额外数据并将其提供到结果数组中。