如何确保在另一堆异步函数调用完成后才会发生一堆异步函数调用?

时间:2015-10-29 03:26:44

标签: javascript node.js promise

我是JavaScript的新手,我认为我尝试做的事情可以使用Promise解决,但在阅读完Mozilla文档后,我无法弄清楚如何实现这一点。

让我用以下代码演示我想要实现的目标。

// file demo.js
function async_print(message, seconds)
{
    setTimeout(function () {
        console.log(message, '(' + seconds + ' s)')
    }, seconds * 1000);
}

// First execute the following three asynchronously
async_print('foo', 1)
async_print('foo', 2)
async_print('foo', 3)

// Then execute the following three asynchronously
async_print('bar', 1)
async_print('bar', 2)
async_print('bar', 3)

// Then execute the following three asynchronously
async_print('baz', 1)
async_print('baz', 2)
async_print('baz', 3)

我得到以下输出。

$ node demo.js 
foo (1 s)
bar (1 s)
baz (1 s)
foo (2 s)
bar (2 s)
baz (2 s)
foo (3 s)
bar (3 s)
baz (3 s)

另外,请参阅JSFiddle:http://jsfiddle.net/3kdwy46r/

我的意图被记录为代码中的注释。我希望首先执行所有'foo'语句。只有在'foo'语句完成后才能执行'bar'语句。只有在'bar'语句完成后才能执行'baz'语句。这意味着输出应该如下所示。

foo (1 s)
foo (2 s)
foo (3 s)
bar (1 s)
bar (2 s)
bar (3 s)
baz (1 s)
baz (2 s)
baz (3 s)

这是否可以在JavaScript或节点中方便地完成,而不依赖于第三方库?例如,JavaScript Promise可以帮助吗?我知道我可能必须修改async_print函数签名或将其包装在其他内容中,以便传递可以调用以指示函数完成的回调。我没有这样的修改。我基本上需要知道如何完成这样的工作。

请您提供完整的代码示例,以便我可以使用它来学习如何在JavaScript中执行此类操作?

1 个答案:

答案 0 :(得分:2)

这是最适合承诺,$(".txt_Idt").datepicker({ changeMonth: true, changeYear: true, dateFormat: 'mm/dd/yy', yearRange: '-115:+1M', maxDate: new Date(), onSelect: function(dateText) { $(".txt_Epdt").datepicker("option", "minDate", dateText); } }); $(".txt_Epdt").datepicker({ changeMonth: true, changeYear: true, dateFormat: 'mm/dd/yy', yearRange: '-115:+95M', onSelect:function(dateText) { $(".txt_Idt").datepicker('option','maxDate',dateText); } }); 和承诺链接的东西。这是一个片段,您可以在现代浏览器中运行以查看输出:



<input type="text" placeholder="Passport Date" class="ipt_Field txt_Idt ipt_required" 
   id="txt_Idt" name="txt_Idt" readonly /> <!--Add readonly here-->
<input type="text" placeholder="Expiry Date" class="ipt_Field txt_Epdt ipt_required" 
   id="txt_Epdt" name="txt_Epdt" readonly /><!--Add readonly here-->
&#13;
&#13;
&#13;

一般的想法是:

  1. 您更改import weblogic.jndi.Environment; import weblogic.security.auth.Authenticate; import javax.security.auth.Subject; for(JmsComponentConfig config : this.config.jmsComponents()){ Environment environment = new Environment(); environment.setProviderUrl(config.url()); environment.setSecurityPrincipal(config.username()); environment.setSecurityCredentials(config.password()); Subject subject = new Subject(); Authenticate.authenticate(environment, subject); } ,以便返回在异步操作完成时解析的承诺。
  2. 您使用Promise.all()告诉您何时完成了一组 // return a promise from this async function that is resolved when done function async_print(message, seconds) { return new Promise(function(resolve) { setTimeout(function () { resolve(); }, seconds * 1000); }).then(function() { log(message, '(' + seconds + ' s)') }); } Promise.all([async_print('foo', 1), async_print('foo', 2), async_print('foo', 3)]).then(function() { return Promise.all([async_print('bar', 1), async_print('bar', 2), async_print('bar', 3)]); }).then(function() { return Promise.all([async_print('baz', 1), async_print('baz', 2), async_print('baz', 3)]); }).then(function() { // everything done here }); function log(x,y) { var div = document.createElement("div"); div.innerHTML = x; if (arguments.length > 1) { div.innerHTML += y; } document.body.appendChild(div); }语句。
  3. 您使用来自async_print()的{​​{1}}处理程序来触发下一组操作(完成所有先前操作后)。
  4. 您返回下一个Promise.all()以便将它们链接在一起,以便按顺序发生这些组。