Javascript 简化嵌套承诺和循环

Javascript 简化嵌套承诺和循环,javascript,angularjs,angular-services,Javascript,Angularjs,Angular Services,我正在开发一款有棱角的应用程序,我试图更好地理解承诺 当我处理异步调用(如$http)时,我通常会将它们包装到服务中,然后在我的控制器中调用它们,如下所示: ... function whatever(arguments) { dataService.getUser(arguments) .then(onUserComplete) .then(dataService.getExtra) .then(onExtraComplete)

我正在开发一款有棱角的应用程序,我试图更好地理解承诺 当我处理异步调用(如$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
()等待一系列承诺

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.all绑定所有承诺。在下一个
.then()
中,所有用户额外的数据都将加载并提供到结果数组中。

仅供参考:尽管JavaScript的提升将导致函数为人所知,但许多具有默认设置的linter会抱怨函数在使用之前没有定义。您的第二个代码段将并行获得所有用户,当收到用户时,您会立即对其进行处理。如果这是你想要的,你的第二个片段是正确的。@manonthemat是的,我知道。我在Delkos主题中使用了括号,它对已经定义的方法使用了不同的颜色。在实际的生产代码中,函数是在使用之前定义的:)@tcooc对不起,但是你确定吗?似乎在我获得所有用户之前,我会按顺序处理每个用户,而不是让他们进入parallel@Donbabbeo为了澄清这一点,您需要获取所有用户,然后并行处理它们(假设
getExtra
是异步的)。