您是否可以避免与Promises一起嵌套? [英] Can you avoid nesting altogether with Promises?

查看:117
本文介绍了您是否可以避免与Promises一起嵌套?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,Promises的主要卖点之一是能够编写平面代码(或者比回调地狱更扁平).

From what I understand one of the main selling points for Promises is the ability to write flat code (or, flatter than callback hell).

尽管在很多情况下,为了使用闭包,我们需要嵌套promise.例如(来自 q 的文档,尽管我使用的是Bluebird):

Though it seems that in many cases we need to nest promises, in order to use closure. For example (from q's docs, though I use Bluebird):

function authenticate() {
    return getUsername()
        .then(function (username) {
            return getUser(username);
        })
        // chained because we will not need the user name in the next event
        .then(function (user) {
            return getPassword()
                // nested because we need both user and password next
                .then(function (password) {
                    if (user.passwordHash !== hash(password)) {
                        throw new Error("Can't authenticate");
                    }
                });
        });
}

是否有一种更干净的方法而不嵌套?

Is there a cleaner way to do this, without nesting?

我已经设法使用.all清理了这个特定的示例,但是在更复杂的情况下,我认为无法做到这一点:

I've managed to clean up this specific example using .all, but there are more complex cases where I don't think it can be done:

function authenticate() {
    return Promise.all([
        getUsername().then(getUser),
        getPassword()
    ]).spread(function (user, password) {
        if (user.passwordHash !== hash(password)) {
            throw new Error('Can\'t authenticate');
        }
    });
}

推荐答案

是的,您始终可以使用Promise作为代理,使用Promise.all(Bluebird中的Promise.join的简写形式)来平整Promise链.毕竟-Promise抽象值,您总是可以在需要时解开Promise,并使其他变量依赖于此.

Yes, you can always flatten a promise chain with Promise.all (shorthand through Promise.join in Bluebird) by using promises for the proxies they are. After all - promises abstract values, you can always unwrap a promise as late as you want and have other variables depend on it.

是否更具可读性是另一个争论:

Whether or not it's more readable is another debate:

foo().then(function(a){
     return bar(a).then(function(b){
          return g(a,b); // "needed" to nest because I wanted `a`
     });
});

可以写为:

var a = foo();
var b = a.then(bar);
Promise.join(a, b, function(a,b){
    return g(a, b); // alternatively, res could have been `Promise.join(a,b, g)`
});

所以通常-您可以总是避免嵌套,但是很多时候您可能不想这么做.

So generally - you can always avoid nesting but a lot of time you might not want to.

就您而言,甚至可以是:

In your case, this can even be:

function authenticate() {
    var userPass = Promise.all([ getUsername().then(getUser), getPassword()]);
    var passHash = userPass.get(0).get("passwordHash");
    var newHash = userPass.get(1).then(hash);     
    var equal = Promise.join(userHash, newHash, function(a, b){ return a !==b });
    return equal.then(function(val){ if(!val) throw new Error("..."); });
}

扑吗?当然.更好的?这是另一个问题.如果您有嵌套的for循环,则可能希望将其保留为嵌套的for循环并嵌套,而不是乱砍该选项并使用单个循环.

Flatter? Sure. Better? That's a whole other question. If you have a nested for loop, you might want to keep it a nested for loop and nest rather than hack around that option and use a single loop.

这篇关于您是否可以避免与Promises一起嵌套?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆