Javascript 使用函数的链承诺不';t返回所需的回调序列

Javascript 使用函数的链承诺不';t返回所需的回调序列,javascript,node.js,promise,q,Javascript,Node.js,Promise,Q,1.我试图在全局承诺对象上使用函数来链接一些承诺。链式排列不像我想的那样有效。以下代码输出1 3 4 2。 我不知道这是什么原因。我的想法是在变量声明过程中,p.then()函数被注册,但不是它的以下承诺,直到p.then()函数返回,它才开始推回调队列中的第二个then函数 为了回答我为什么这样做的问题,我尝试使用一个构建器模式进行一系列操作。 例如,builder().setupTestEnv().connectToDatabase().setupAuthServer().setupAuth

1.我试图在全局承诺对象上使用函数来链接一些承诺。链式排列不像我想的那样有效。以下代码输出1 3 4 2。 我不知道这是什么原因。我的想法是在变量声明过程中,p.then()函数被注册,但不是它的以下承诺,直到p.then()函数返回,它才开始推回调队列中的第二个then函数

为了回答我为什么这样做的问题,我尝试使用一个构建器模式进行一系列操作。 例如,builder().setupTestEnv().connectToDatabase().setupAuthServer().setupAuthClient()。此链中的每个函数都用于执行_globalPromiseObject.then()以链接以下操作

我知道另一种解决方案是,用execute()调用结束构建器链,该调用运行Q.all()以按顺序运行所有承诺。但我只是好奇这个承诺链的行为

const Q = require('q');

const p = Q();

p
.then(
    function(){
        console.log(1);
    }
)
.then(
    function(){
        console.log(2);
    }
);

function foo(){
    p.then(
        function () {
            console.log(3);
        }
    );
}

function bar(){
    p.then(
        function () {
            console.log(4);
        }
    );
}

foo();
bar();

不确定这是否100%回答了您的问题,但在您的示例中,从有意义的陈述的角度来看这一点可能会有所帮助:

  • p.then()
  • foo()
  • bar()
  • 最后,#1的
    然后
    开火
  • 这三个操作紧随其后,同步进行。让我们删除
    foo
    bar
    包装器,就好像您编写了它们的内容而不是调用它们一样:

  • p.then(/*log1*/)
  • p.then(/*log3*/)
    foo的内容
  • p.then(/*log4*/)
    bar的内容
  • 最后,#1的
    然后
    开火

  • 您可以从相应的函数
    返回
    foo()
    bar()
    ,然后将
    foo
    bar
    传递到
    。然后()
    。然后(foo)。然后(bar)
    返回
    foo()
    bar()
    传递。然后(函数(){return foo()}

    const p=Promise.resolve();
    P
    .那么(
    函数(){
    控制台日志(1);
    }
    )
    .那么(
    函数(){
    控制台日志(2);
    }
    )
    .然后(函数(){
    返回foo()
    })
    .然后(函数(){
    返回条()
    })
    函数foo(){
    返回p(
    函数(){
    控制台日志(3);
    返回
    }
    );
    }
    功能条(){
    返回p(
    函数(){
    控制台日志(4);
    返回
    }
    );
    
    }
    如果你想要一个序列,你应该写一条链而不是三条。如果你想要序列1,2,3,4,为什么你要让一切都依赖于
    p
    ?你必须把它们连在一起,相互附加,而不是同一个承诺!您将它们全部链接到
    p
    承诺,因此订单将是您在
    p
    上将它们附加到链上的订单。始终将回调(使用
    。然后(…)
    )链接到它应该依赖(并等待)的承诺。这可以是一个实际的链,也可以拆分一个链并为每个步骤使用变量。此方法还有助于创建承诺依赖树,而不仅仅是(线性)链——您不限于线性序列。
    then
    从不同步启动其回调。不确定我是否误解了你的意思?@Bergi是的。在本例中,除了这些回调之外,没有任何事情发生。不是回调,而是程序中对自身的调用是同步发生的,顺序是这样的。酷。这是有道理的。谢谢因为我对当时的承诺有不同的理解。我认为类似于Promise.then()的东西是同步返回的,然后它将继续构建下面的then()链。但它不这样做是有道理的。因为遵循then()链的行为与先前then()结果的返回值相关。我们必须先解析first-then()来注册下面的then()函数。。。然后(foo)。然后(bar)
    就足够了。@Lokua请看@guest271314的右边。对这个问题的回答还指出,“通常你应该传递
    f
    ,而不是
    函数(x){return f(x);}
    ”。这通常适用于JS中的函数,而不仅仅是承诺<代码>常量add1=x=>x+1;number.map(add1)
    <代码>p.then(doA).then(handleAReturn).catch(handleError)
    非常优雅。