简体   繁体   English

无法弄清楚如何用Q链接嵌套的Promise

[英]Cannot figure out how to chain nested promise with Q

I'm new into node.js and promise (Q), so please be kind. 我是node.js的新手并承诺(Q),所以请保持友好。 I want to chain nested promises with his executing parent chain and i can't find how to. 我想将嵌套的诺言与他执行的父链链接起来,但我找不到方法。

I've made a toy script to illustrate my pb, you can launch it with node.js : 我制作了一个玩具脚本来说明我的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);

It display: 它显示:

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

I would like to chain the last line sub2 with fn3 . 我想将最后一行sub2fn3

Any help appreciated, Thanks. 任何帮助表示赞赏,谢谢。

 setTimeout(function() { … return sub1(ctx).then(sub2); }, …) 

Here you're trying to return from an asynchronous plain callback. 在这里,您尝试从异步普通回调return You cannot do that, the result will be lost as setTimeout does not care about it. 您不能这样做,结果将丢失,因为setTimeout不关心它。

You can only return from .then() callbacks. 您只能从.then()回调return In your case, it would look like this: 在您的情况下,它看起来像这样:

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);
        }
    });
}

You also can see that you're always using Q.defer together with a setTimeout now. 您还可以看到您现在一直在使用Q.defersetTimeout You should make a helper function for that which returns a promise, and use deferreds as seldom as possible . 您应该为返回promise的函数创建一个辅助函数,并尽可能少使用deferreds

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM