多次致电承诺

时间:2017-06-29 12:23:45

标签: typescript

在我的角度应用程序中,我使用承诺在我的服务中调用方法,但因为我需要多次调用它,所以我在for循环中调用它。

for(let item of this.arrayName)
{
   this.service.funcName(item.name).then(result => {                  
       //handle result                   
   }).catch(err => {                  
       //handle error
   });
}

但是在同时从多个来电获得结果时会发生什么?承诺知道如何处理它?它是否分别处理每个结果? 还是我需要锁定代码? 提前谢谢。

3 个答案:

答案 0 :(得分:0)

是的,承诺"知道"如何处理它。这是JavaScript的本质。 JavaScript事件循环在单个线程上运行,当IO操作(ajax,indexeddb,filesystem等...)完成时,回调将附加到事件循环连续使用的消息队列中。这样你就不必担心任何竞争条件。此外,ECMAScript规范经过精心设计,可以隐藏每个可能发生竞争条件的地方。

这就是你必须避免编写阻塞代码的原因。如果您的代码阻塞,整个EventLoop将被阻止。现在很难在JavaScript中创建这样的阻塞代码,但仍然不是不可能的。

请参阅Concurrency model and Event Loop on MDN

答案 1 :(得分:0)

您所做的是为this.arrayName中的每个项目创建一个承诺。

这应该可以正常工作,只要每个项目的处理完全独立。但是你需要注意的是,在解决并随后处理promise之前,你的代码执行将继续超出for循环。因此,可能希望在继续之前等待所有承诺完全解决。

您可以使用以下内容执行此操作:

Promise.all(this.arrayName.map(name => {
   return this.service.funcName(name).then(result => {                  
       //handle result                   
   }).catch(err => {                  
       //handle error
   });
})
.then(...) // all success - do success case
.catch(...) // some failed - handle error case

答案 2 :(得分:0)

Samir said是正确的。每次调用该函数时,它都会调用return语句return new Promise(...)(这是使用promises的预期方式)。

JavaScript也有闭包的概念,关闭意味着传递给函数的参数只出现在函数的执行中。所有基元(包括对象引用都是“关闭”,因此当循环更改item时,它不会影响先前的函数调用。

唯一要问的问题是你是否真的希望它们全部并行执行。您拥有的循环将执行所有循环,而无需等待先前的承诺解决。

由于您使用的是Angular,请查看Observables。它们的学习曲线有些陡峭(使用时会有不同的看法),但一旦你学会了它们就非常有用。

帮助我最终了解Observables的介绍是这样的:https://gist.github.com/staltz/868e7e9bc2a7b8c1f754