在检索到promise之后定义then()

时间:2015-11-27 14:04:32

标签: javascript angularjs asynchronous angular-promise

我有一个关于将回调函数附加到AngularJS中的promise的问题。

假设我有一个带有返回promise的函数的服务。我调用了这个函数并在本地存储了promise。然后我在promise上定义了一个回调函数。

var promise = TestService.get();
console.log('We have a promise!');
promise.then(function (result){
  console.log('Here is the result:'+result);
});

在这种情况下,我们存在潜在的风险。如果在我们到达promise.then(...之前解决了承诺,则结果不会输出到控制台(直到下一个摘要周期)。

或者,我可以像这样编写上面的代码:

TestService.get().then(function (result){
  console.log('Here is the result:'+result);
});

我的问题:

第二个例子中是否已减轻风险?如果没有,在附加回调之前,如何确保承诺无法解决? 一个稍微更精细的答案比是/否将非常感激:)

3 个答案:

答案 0 :(得分:4)

您所描述的行为不会发生,可以通过一个简单的示例看出。在这里,我们有一个简单的承诺工厂,它返回一个立即解决的承诺。

'use strict';
var make = function() {
  return new Promise(function(resolve, reject) {
    resolve(2);
  });
};

然后我们创建一个新的promise并将其分配给变量

var prom = make();

我们可以根据需要随时拨打.then。这是因为承诺是不可变的,我们不会通过链接方法来改变原始值。

prom.then(a => console.log(a));
// 2
prom.then(a => console.log(a));
// 2

答案 1 :(得分:2)

  

假设我有一个带有返回promise的函数的服务。我调用了这个函数并在本地存储了promise。然后我在promise上定义了一个回调函数。

不,你没有附加回调。当您调用然后方法时,您正在执行一项名为 promise chaining 的操作。每次调用然后都会返回一个 new promise对象,该对象将解析为前一个promise所返回的值。

例如;

var promise1 = TestService.get();
var promise2 = promise1.then(function(value) {
                  console.log('service resolved: '+value);
                  return "Hello World";
               });
var promise3 = promise2.then(function(value) {
                  console.log(value);
               });
promise3.then(function(value) {
       console.log(value);
});

以上示例将输出以下内容。

**some value from TestService**
Hello World
undefined

我们不知道谁最初解决了第一个承诺的价值。我们所知道的是该服务返回了一个承诺。从那一刻起,我们可以通过添加更多调用然后来链接承诺。

  

在这种情况下,我们存在潜在的风险。如果在我们到达promise.then之前解决了承诺(...,结果没有输出到控制台(直到下一个摘要周期)。

不,消除承诺的时间或消息无关紧要。即使在解决之后,承诺也可以多次调用它的然后方法。只要它没有被拒绝,它将继续解决价值。解决或拒绝承诺的决定超出了成功或失败回调的范围。

您可以创建一个承诺,将其解析为一个值,等待多个摘要并将处理程序添加到然后,它仍将按预期工作。

  

第二个例子中是否已减轻风险?如果没有,在附加回调之前,如何确保承诺无法解决?

将承诺视为容器。它们将保持您期望的价值,您必须调用然后才能获得它。如果由于某种原因该值不可用,您可以通过使用错误回调找出原因。 promises的方面纯粹是一个异步问题,而且这个想法是承诺隐藏这些问题。

答案 2 :(得分:1)

JavaScript不是多线程的,在您的代码返回之前,您的异步AJAX调用实际上并不是由浏览器完成的。

var promise = TestService.get();
for (var i= 0;i<100000;i++){
    console.log(i)
}
console.log('We have a promise!');
promise.then(function (result){
    console.log('Here is the result:'+result);
});

使用网络分析仪观察。