angularjs 延期承诺不延期
angularjs deferred promise not deferring
努力让承诺在 angularjs 服务提供商中正常工作
我读过 docs as well as numerous examples (here, here and here),我想我的语法没问题
(虽然很明显有些不对劲)
应用程序模块和控制器看起来像
var myApp = angular.module('myApp', []);
myApp.controller('Controller_1', ['$scope', 'Service_1', function($scope, Service_1) {
var myName = "Ben";
Service_1.slowService(myName)
.then(Service_1.fastService(name));
$scope.myName = myName;
}]);
服务(具有慢速功能)如下所示:
myApp.service('Service_1', function($q) {
this.slowService = function (name) {
var deferred = $q.defer();
console.log('Start of slowService:', name, Date.now());
setTimeout(function() {
console.log('setTimeout name:', name, Date.now());
if(name){
name = 'Hello, ' + name + " is learning Angularjs";
alert(name);
console.log('name:', name);
deferred.resolve(name);
} else {
deferred.reject('No name supplied !');
}
}, 3000);
return deferred.promise;
};
this.fastService = function(name){
console.log('Start of fastFunction:', name, Date.now());
alert('Hello ' + name + ' - you are quick!');
};
});
控制台输出如下所示:
Start of slowService: Ben 1420832940118
Start of fastFunction: result 1420832940122
setTimeout name: Ben 1420832948422
name: Hello, Ben is learning Angularjs
fastService
在 slowService
完成之前开始,尽管在 Service_1
中使用了延迟对象/承诺并在控制器中使用了 .then
...
任何人都可以指出代码有什么问题吗?
jsfiddle 是 here
编辑: 将快速功能放入服务中,这样就不会与提升等混淆 - 结果仍然相同 - js fiddle 已更新
您将函数传递给 then()
部分的方式不正确。
像这样传递它:
Service_1.slowService(myName)
.then(function(){fastFunction(name)});
The fastService is starting before the slowService completes
那是因为您在 slowService 异步回调之前执行 fastService 函数 runs.Instead 您需要提供该函数的引用。即 .then(Service_1.fastService(name));
应该是 .then(Service_1.fastService);
或 .then(function(name){ Service_1.fastService(name); });
否则 fastservice 将立即 运行,在 slowService 运行s.
的异步部分之前
使用 $timeout
的优点是它已经 return 是一个承诺,因此您不需要创建延迟对象并导致 deferred anti-pattern。
myApp.service('Service_1', function($q, $timeout) { //<-- Inject timeout
this.slowService = function (name) {
console.log('Start of slowService:', name, Date.now());
return $timeout(function() {
console.log('setTimeout name:', name, Date.now());
if(name){
name = 'Hello, ' + name + " is learning Angularjs";
return name; //return data
}
//Reject the promise
return $q.reject('No name supplied !');
}, 3000);
};
//...
});
并且在消费时只是连锁:
Service_1.slowService(myName)
.then(Service_1.fastService);
因此,即使您在原始方法中使用 $http
而不是超时,也只是 return 来自 http 的承诺,而不是创建延迟对象。另外请记住,当您使用语法 .then(Service_1.fastService);
时,如果您指的是快速服务中的 this
上下文,则它不会是服务实例。
由于您的 slowService
解析为 name
值,这就是您传递给 then
的函数的参数。你可以这样做:
Service_1.slowService(myName)
.then(function(name){ Service_1.fastFunction(name); });
但即使这样也是多余的,因为您只是将 name
传递给另一个采用单个 name
参数的函数。
这就是您所需要的:
Service_1.slowService(myName)
.then(Service_1.fastFunction);
注意第二行没有 (name)
。我们想将 函数 传递给 then
。您所做的是立即调用该函数并将 undefined
传递给 then
.
YAAK 是正确的。你也可以这样写:
Service_1.slowService(myName)
.then(fastService);
只是澄清一下我非常确定发生的事情:
then
函数正在为承诺被解决或拒绝时注册回调。您不需要传递函数参数,因为当您 resolve
使用您试图传递给回调函数的任何数据时,这已经完成了。当你在那里有 fastService(name)
时,它只是在它到达那行代码后立即执行该函数,而不是等待 promise 解析,因为它是一个函数调用,而不是一个函数对象。
有趣的是,fastService 返回 'result' 作为名称,而不是说名称未定义。我不知道它从哪里获取该变量的值。
努力让承诺在 angularjs 服务提供商中正常工作 我读过 docs as well as numerous examples (here, here and here),我想我的语法没问题 (虽然很明显有些不对劲)
应用程序模块和控制器看起来像
var myApp = angular.module('myApp', []);
myApp.controller('Controller_1', ['$scope', 'Service_1', function($scope, Service_1) {
var myName = "Ben";
Service_1.slowService(myName)
.then(Service_1.fastService(name));
$scope.myName = myName;
}]);
服务(具有慢速功能)如下所示:
myApp.service('Service_1', function($q) {
this.slowService = function (name) {
var deferred = $q.defer();
console.log('Start of slowService:', name, Date.now());
setTimeout(function() {
console.log('setTimeout name:', name, Date.now());
if(name){
name = 'Hello, ' + name + " is learning Angularjs";
alert(name);
console.log('name:', name);
deferred.resolve(name);
} else {
deferred.reject('No name supplied !');
}
}, 3000);
return deferred.promise;
};
this.fastService = function(name){
console.log('Start of fastFunction:', name, Date.now());
alert('Hello ' + name + ' - you are quick!');
};
});
控制台输出如下所示:
Start of slowService: Ben 1420832940118
Start of fastFunction: result 1420832940122
setTimeout name: Ben 1420832948422
name: Hello, Ben is learning Angularjs
fastService
在 slowService
完成之前开始,尽管在 Service_1
中使用了延迟对象/承诺并在控制器中使用了 .then
...
任何人都可以指出代码有什么问题吗?
jsfiddle 是 here
编辑: 将快速功能放入服务中,这样就不会与提升等混淆 - 结果仍然相同 - js fiddle 已更新
您将函数传递给 then()
部分的方式不正确。
像这样传递它:
Service_1.slowService(myName)
.then(function(){fastFunction(name)});
The fastService is starting before the slowService completes
那是因为您在 slowService 异步回调之前执行 fastService 函数 runs.Instead 您需要提供该函数的引用。即 .then(Service_1.fastService(name));
应该是 .then(Service_1.fastService);
或 .then(function(name){ Service_1.fastService(name); });
否则 fastservice 将立即 运行,在 slowService 运行s.
使用 $timeout
的优点是它已经 return 是一个承诺,因此您不需要创建延迟对象并导致 deferred anti-pattern。
myApp.service('Service_1', function($q, $timeout) { //<-- Inject timeout
this.slowService = function (name) {
console.log('Start of slowService:', name, Date.now());
return $timeout(function() {
console.log('setTimeout name:', name, Date.now());
if(name){
name = 'Hello, ' + name + " is learning Angularjs";
return name; //return data
}
//Reject the promise
return $q.reject('No name supplied !');
}, 3000);
};
//...
});
并且在消费时只是连锁:
Service_1.slowService(myName)
.then(Service_1.fastService);
因此,即使您在原始方法中使用 $http
而不是超时,也只是 return 来自 http 的承诺,而不是创建延迟对象。另外请记住,当您使用语法 .then(Service_1.fastService);
时,如果您指的是快速服务中的 this
上下文,则它不会是服务实例。
由于您的 slowService
解析为 name
值,这就是您传递给 then
的函数的参数。你可以这样做:
Service_1.slowService(myName)
.then(function(name){ Service_1.fastFunction(name); });
但即使这样也是多余的,因为您只是将 name
传递给另一个采用单个 name
参数的函数。
这就是您所需要的:
Service_1.slowService(myName)
.then(Service_1.fastFunction);
注意第二行没有 (name)
。我们想将 函数 传递给 then
。您所做的是立即调用该函数并将 undefined
传递给 then
.
YAAK 是正确的。你也可以这样写:
Service_1.slowService(myName)
.then(fastService);
只是澄清一下我非常确定发生的事情:
then
函数正在为承诺被解决或拒绝时注册回调。您不需要传递函数参数,因为当您 resolve
使用您试图传递给回调函数的任何数据时,这已经完成了。当你在那里有 fastService(name)
时,它只是在它到达那行代码后立即执行该函数,而不是等待 promise 解析,因为它是一个函数调用,而不是一个函数对象。
有趣的是,fastService 返回 'result' 作为名称,而不是说名称未定义。我不知道它从哪里获取该变量的值。