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

时间:2017-10-01 20:08:15

标签: javascript node.js promise q

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

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

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

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

2 个答案:

答案 0 :(得分:0)

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

  1. <form name="UpdateFishForm" enctype="multipart/form-data" action="Query/UpdateFish.cfc?PK=#PK#"> <h1>Update #FishName#</h1> <label>Fish Name:</label><input name="FishName" value="#FishName#" /> <input name="PK" value="#PK#" hidden="true"> <br /> <label>Fish Genus:</label> <select name="FishGenus"> <option value="#FishGenus#" selected="selected"> <cfif #FishGenus# eq 1> Hap <cfelseif #FishGenus# eq 2> Peacock <cfelseif #FishGenus# eq 3> Mbuna <cfelseif #FishGenus# eq 4> Tang <cfelseif #FishGenus# eq 5> Victorian <cfelseif #FishGenus# eq 6> Cat Fish / Pleco <cfelse> Other </cfif> </option> <option value="1">Hap</option> <option value="2">Peacock</option> <option value="3">Mbuna</option> <option value="4">Tang</option> <option value="5">Victorian</option> <option value="6">Cat Fish / Pleco</option> <option value="7">Other</option> </select> <br /> <label>Fish Image:</label><input name="FishImage" type="file" value="#FishImage#" /> <br /> <label>Fish Type:</label> <select name="FishType" Placeholder="FishType"> <option value="#FishType#" selected="selected">#FishType#</option> <option value="Wild Caught">Wild Caught</option> <option value="F1">F1</option> <option value="F2">F2</option> <option value="Tank Raised">Tank Raised</option> </select> <br /> <label>Fish Directory:</label> <table> <tr> <th>Fish Size</th> <th>Fish Sex</th> <th>Fish Quantity</th> <th>Fish Price</th> </tr> <tr> <td><label>Fish ##1:</label><input name="Fish1size" value="#Fish1Size#"/></td> <td><select name="Fish1Sex"> <option value="#Fish1Sex#">#Fish1Sex#</option> <option value="Male">Male</option> <option value="Female">Female</option> <option value="Unsexed">Unsexed</option> </select> </td> <td><input name="Fish1Qty" value="#Fish1Qty#"></td> <td><input name="Fish1Price" value="#Fish1Price#"></td> </tr> <tr> <td><label>Fish ##2:</label><input name="Fish2size" value="#Fish2Size#"/></td> <td><select name="Fish2Sex"> <option value="#Fish2Sex#">#Fish2Sex#</option> <option value="Male">Male</option> <option value="Female">Female</option> <option value="Unsexed">Unsexed</option> </select> </td> <td><input name="Fish2Qty" value="#Fish2Qty#"></td> <td><input name="Fish2Price" value="#Fish2Price#"></td> </tr> <tr> <td><label>Fish ##3:</label><input name="Fish3size" value="#Fish3Size#"/></td> <td><select name="Fish3Sex"> <option value="#Fish3Sex#">#Fish3Sex#</option> <option value="Male">Male</option> <option value="Female">Female</option> <option value="Unsexed">Unsexed</option> </select> </td> <td><input name="Fish3Qty" value="#Fish3Qty#"></td> <td><input name="Fish3Price" value="#Fish3Price#"></td> </tr> <tr> <td><label>Fish ##4:</label><input name="Fish4size" value="#Fish4Size#"/></td> <td><select name="Fish4Sex"> <option value="#Fish4Sex#">#Fish4Sex#</option> <option value="Male">Male</option> <option value="Female">Female</option> <option value="Unsexed">Unsexed</option> </select> </td> <td><input name="Fish4Qty" value="#Fish4Qty#"></td> <td><input name="Fish4Price" value="#Fish4Price#"></td> </tr> <tr> <td><label>Fish ##5:</label><input name="Fish5size" value="#Fish5Size#"/></td> <td><select name="Fish5Sex"> <option value="#Fish5Sex#">#Fish5Sex#</option> <option value="Male">Male</option> <option value="Female">Female</option> <option value="Unsexed">Unsexed</option> </select> </td> <td><input name="Fish5Qty" value="#Fish5Qty#"></td> <td><input name="Fish5Price" value="#Fish5Price#"></td> </tr> <tr> <td><label>Fish ##6:</label><input name="Fish6size" value="#Fish6Size#"/></td> <td><select name="Fish6Sex"> <option value="#Fish6Sex#">#Fish6Sex#</option> <option value="Male">Male</option> <option value="Female">Female</option> <option value="Unsexed">Unsexed</option> </select> </td> <td><input name="Fish6Qty" value="#Fish6Qty#"></td> <td><input name="Fish6Price" value="#Fish6Price#"></td> </tr> </table> <p>Discription</p> <textarea cols="70" rows="6" name="FishDescription" style="margin-left:5px; margin-top:-10px">#FishDescription#</textarea> <br /> <input type="submit" name="submit" /> </form> </cfoutput>
  2. p.then()
  3. foo()
  4. 最后,#1的bar()开火
  5. 这三个操作紧接着发生,同步。让我们删除thenfoo包装器,就像你编写内容而不是调用它们一样:

    1. bar
    2. p.then(/* log 1 */)内容foo
    3. p.then(/* log 3 */)栏内容
    4. 最后,#1的p.then(/* log 4 */)开火

答案 1 :(得分:0)

您可以从相应的功能return foo()bar(),然后将foobar传递给.then() .then(foo).then(bar)来自return

foo() bar().then(function(){ return foo() })

&#13;
&#13;
const p = Promise.resolve();

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

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

function bar() {
  return p.then(
    function() {
      console.log(4);
      return
    }
  );
}
&#13;
&#13;
&#13;