Javascript 无法确定如何将嵌套承诺与Q链接

Javascript 无法确定如何将嵌套承诺与Q链接,javascript,node.js,promise,q,Javascript,Node.js,Promise,Q,我是node.js和promise(Q)的新手,所以请友好一点。 我想把嵌套的承诺和他正在执行的父链连接起来,但我找不到方法 我制作了一个玩具脚本来演示我的pb,您可以使用node.js启动它: var Q = require("q"); function init() { return {nbIn: 0, nbOut: 0, stop: false}; } function fn1(ctx) { var deferred = Q.defer(); console.

我是node.js和promise(Q)的新手,所以请友好一点。 我想把嵌套的承诺和他正在执行的父链连接起来,但我找不到方法

我制作了一个玩具脚本来演示我的pb,您可以使用node.js启动它:

var Q = require("q");

function init() {
    return {nbIn: 0, nbOut: 0, stop: false};
}

function fn1(ctx) {
    var deferred = Q.defer();

    console.log("fn1:" + JSON.stringify(ctx));
    setTimeout(function() {
        console.log("fn1: resolve");
        deferred.resolve(ctx);
    }, 1000)

    return deferred.promise;
}

function sub1(ctx) {
    var deferred = Q.defer();

    console.log("sub1:" + JSON.stringify(ctx));
    setTimeout(function() {
        ++ctx.nbIn;
        console.log("sub1: resolve");
        deferred.resolve(ctx);
    }, 1000);

    return deferred.promise;
}

function sub2(ctx) {
    var deferred = Q.defer();

    console.log("sub2:" + JSON.stringify(ctx));
    setTimeout(function() {
        ++ctx.nbOut;
        if(ctx.nbOut === 3) {
            console.log("sub2: resolve");
            ctx.stop = true;
            deferred.resolve(ctx);
        }
        else {
            console.log("sub2: promise");
            return sub1(ctx).then(sub2);
        }
    }, 1000);

    return deferred.promise;
}

function fn2(ctx) {
    console.log("fn2:" + JSON.stringify(ctx));
    return sub1(ctx).then(sub2);
}

function fn3(ctx) {
    console.log("fn3:" + JSON.stringify(ctx));
}

Q.fcall(init).then(fn1).then(fn2).then(fn3);
它显示:

fn1:{"nbIn":0,"nbOut":0,"stop":false}
fn1: resolve
fn2:{"nbIn":0,"nbOut":0,"stop":false}
sub1:{"nbIn":0,"nbOut":0,"stop":false}
sub1: resolve
sub2:{"nbIn":1,"nbOut":0,"stop":false}
sub2: promise
sub1:{"nbIn":1,"nbOut":1,"stop":false}
sub1: resolve
sub2:{"nbIn":2,"nbOut":1,"stop":false}
sub2: promise
sub1:{"nbIn":2,"nbOut":2,"stop":false}
sub1: resolve
sub2:{"nbIn":3,"nbOut":2,"stop":false}
sub2: resolve
我想用
fn3
链接最后一行
sub2

谢谢你的帮助

在这里,您试图从异步普通回调返回
。您不能这样做,结果将丢失,因为
setTimeout
不关心它

只能从
返回
。然后()
回调。在您的情况下,它将如下所示:

function sub2(ctx) {
    var deferred = Q.defer();

    console.log("sub2:" + JSON.stringify(ctx));
    setTimeout(function() {
        deferred.resolve(ctx);
    }, 1000);

    return deferred.promise.then(function(ctx) {
        ++ctx.nbOut;
        if (ctx.nbOut === 3) {
            console.log("sub2: resolve");
            ctx.stop = true;
            return ctx;
        } else {
            console.log("sub2: promise");
            return sub1(ctx).then(sub2);
        }
    });
}

您还可以看到,您现在总是将
Q.defer
setTimeout
一起使用。您应该为返回承诺的对象创建一个helper函数。

好的,我明白了
setTimeout
只是用来模拟真正的异步函数,比如
db.connect
/
query
/
insert
。好吧,这个参数也适用于它们:将它们尽可能紧密地包装在只给出承诺而不进行处理的助手函数(or)中。用这些承诺完成所有的数据操作和流程逻辑。
function sub2(ctx) {
    var deferred = Q.defer();

    console.log("sub2:" + JSON.stringify(ctx));
    setTimeout(function() {
        deferred.resolve(ctx);
    }, 1000);

    return deferred.promise.then(function(ctx) {
        ++ctx.nbOut;
        if (ctx.nbOut === 3) {
            console.log("sub2: resolve");
            ctx.stop = true;
            return ctx;
        } else {
            console.log("sub2: promise");
            return sub1(ctx).then(sub2);
        }
    });
}