在promise库Q中,您可以执行以下操作来按顺序链接promise:
var items = ['one', 'two', 'three'];
var chain = Q();
items.forEach(function (el) {
chain = chain.then(foo(el));
});
return chain;
Run Code Online (Sandbox Code Playgroud)
但是,以下内容不适用于$ q:
var items = ['one', 'two', 'three'];
var chain = $q();
items.forEach(function (el) {
chain = chain.then(foo(el));
});
return chain;
Run Code Online (Sandbox Code Playgroud) 有人可以告诉我,如果使用错误回调与catch函数之间存在差异$q.promise吗?
例如两个代码片段在功能上是等价的吗?
function doSomething0() {
var deferred = $q.defer();
...
return deferred.promise;
}
doSomething0()
.then(doSomething1)
.then(doSomething2)
.then(doSomething3)
.catch(function (err) {
// do something with `err`
});
Run Code Online (Sandbox Code Playgroud)
与
function doSomething0() {
var deferred = $q.defer();
...
return deferred.promise;
}
function errorHandler(err) {
// do something with `err`
}
doSomething0()
.then(doSomething1, errorHandler)
.then(doSomething2, errorHandler)
.then(doSomething3, errorHandler);
Run Code Online (Sandbox Code Playgroud)
如果是这样,为什么要使用第二个呢?在我看来,它看起来更加丑陋并导致更多的代码重复?
有没有办法用angular $ http模块模拟jquery'完整'回调?无论请求是成功还是失败,我都会想要执行一些代码,此时我发现自己必须写这个:
$http.get(someUrl).success(function(){
successCode();
completeCode();
}).error(function(){
errorCode();
completeCode();
})
Run Code Online (Sandbox Code Playgroud)
但我宁愿写下这样的东西:
$http.get(someUrl).success(function(){
successCode();
}).error(function(){
errorCode();
}).complete(function(){
completeCode();
})
Run Code Online (Sandbox Code Playgroud)
我也试过使用promise API,但我最终遇到了同样的问题.有什么建议吗?
我目前正在使用angular的$ q服务来进行API调用,如下所示:
var deferred = $q.defer();
$http.get(config.apiHost + details.url)
.success(function (data) {
deferred.resolve(data);
}).error(function (msg) {
deferred.reject(msg);
});
return deferred.promise;
Run Code Online (Sandbox Code Playgroud)
但是我们也可以在不使用$ q的情况下使用这种方法:
return $http.get(config.apiHost + details.url)
.success(function (data) {
return data;
}).error(function (msg) {
return msg;
});
Run Code Online (Sandbox Code Playgroud)
并且当$ http本身返回承诺时,我也可以使用更简化的方法:
$http.get(config.apiHost + 'posts')
.success(function (data) {
console.log(data)
}).error(function (msg) {
console.log(msg);
});
Run Code Online (Sandbox Code Playgroud)
那么所有这些特别是在$ q和$ http之间有什么区别,因为两者都返回promise并且都是异步的?angular是否为$ q提供了一些额外的功能?我找不到任何好的答案.
在设置依赖于该信息的一堆服务之前,我需要从服务器获取一些信息(模式).
我的服务器提供了一个定义模型各种属性的模式.在我的角度代码中,我有一个获取此架构的服务:
services.factory('schema', function($q, $http) {
var deferred = $q.defer();
$http.get('schema/').then(function(response) {
schema = // some function of response.data
deferred.resolve(schema);
}, function() {
deferred.reject('There was a problem fetching the schema');
});
return deferred.promise;
});
Run Code Online (Sandbox Code Playgroud)
我想将架构对象而不是promise作为注入依赖于架构的其他服务.$ routeProvider允许我们为控制器执行此操作:
app.config(function($routeProvider) {
$routeProvider.
when('/', {
controller: 'SomeCtrl',
resolve: {
schema: 'schema'
},
...
});
});
Run Code Online (Sandbox Code Playgroud)
这允许我像这样定义SomeCtrl:
controllers.controller('SomeCtrl', function($scope, schema) {
// schema is an object
...
});
Run Code Online (Sandbox Code Playgroud)
但对于服务,我必须这样做:
services.factory('SomeService', function(schema) {
// schema is a promise
schema.then(function(schema) {
...
});
});
Run Code Online (Sandbox Code Playgroud)
有什么方法可以做到这一点吗?
我想知道是否有可能进行使用的服务调用,$http因此它直接返回数据而不返回承诺?我试图使用$q和推迟没有任何运气.
这就是我的意思:
我有一个服务:
angular.module('myModule').factor('myService', ['$http', '$q',
function($http, $q) {
// Public API
return {
myServiceCall: function() {
return $http.get('/server/call');
}
};
}
]);
Run Code Online (Sandbox Code Playgroud)
这就是我所说的:
// My controller:
myService.myServiceCall().then(function(data) {
$scope.data = data;
});
Run Code Online (Sandbox Code Playgroud)
我想避免这种情况,而是希望:
$scope.data = myService.myServiceCall();
Run Code Online (Sandbox Code Playgroud)
我希望它在那条线上完全解决,是否可能?
我已经尝试了$ q,defer和'then'方法的一些组合,但是由于方法立即返回,所以似乎无法正确使用它.
编辑:
如果你想知道为什么,主要的原因是我想简化控制器代码,这很容易用ngResource完成,因为这些调用会在模板中自动解决,所以我想避免需要做整个'.then'每次.
这并不是说我不喜欢Async本质,我们的大部分代码都使用它,只是在某些情况下,采用同步方式很有帮助.
我认为,就像你们中的一些人已经指出的那样,我将使用$ resource来获得足够接近的解决方案.
如果页面关闭,我想发送$ http.get.然后我找不到promises无法解决的问题,
因为如果最后一个方法返回,页面就会被销毁.
以下不起作用,因为onbeforeunload无法解析promises /不等待它们:
window.onbeforeunload = function(
$http.get('http://someth.ing/update-state?page=unloaded').then(function(){
// never called... never sent...
}
}
Run Code Online (Sandbox Code Playgroud)
我知道,你可以使用默认的同步HTTP方法,但问题通常是我们如何同步/等待promises在这里解决.
我的想法是这样的:
window.onbeforeunload = function(){
var ready = false;
$http.get('http://someth.ing/update-state?page=unloaded').then(function(){
ready=true;
}
// I don't see any other opportunity to sync a promise here than this:
while(!ready) angular.noop();
// big question: did $http call the server now? Can we finally return in this method to let the browser 'exit' the page?
}
Run Code Online (Sandbox Code Playgroud)
RFC
javascript synchronization onbeforeunload angularjs angular-promise
我有以下小提琴:http: //jsfiddle.net/thelgevold/3uv9nnjm/6/
angular.module('hello',[]).controller('helloController',function($q){
console.clear();
function someService(){
var deferred = $q.defer();
deferred.reject({e:'error'});
return deferred.promise;
}
function callService(){
return someService().then(function(obj){
console.log('first then');
}).
catch(function(e){
console.log('error1');
var deferred = $q.defer();
deferred.reject({e:'error'});
return deferred.promise;
});
}
callService().catch(function(e){
console.log('error2');
}).then(function(e){
console.log('second then');
});
});
Run Code Online (Sandbox Code Playgroud)
它基本上只是一个快速的$ q承诺POC.我的问题是:为什么在承诺被拒绝时会调用last then子句?输出如下:
ERROR1
误差2
第二个
我理解为什么会打印error1/error2,但我认为第二个字符串不应该打印,因为承诺被拒绝了.我认为它会省略"第二个然后",出于同样的原因,"第一个然后"被省略.有什么想法吗?
我正在尝试多次$http调用,我的代码看起来像这样:
var data = ["data1","data2","data3"..."data10"];
for(var i=0;i<data.length;i++){
$http.get("http://example.com/"+data[i]).success(function(data){
console.log("success");
}).error(function(){
console.log("error");
});
}
Run Code Online (Sandbox Code Playgroud)
我怎么能承诺知道所有的$http电话都是成功的?如果其中任何一个失败,将执行一些操作.
我正在尝试理解promise API和链接,特别$timeout是使用时的时间.then().我对以下内容的期望是,自从$timeout返回一个承诺后,.then()在它解决之前不会被调用.
但是ABAB不是ABAB,而是ABBA.
如何使用promise API确保在执行执行$timeout之前长时间运行的调用(或使用延迟调用)实际上已完成.then()?
码
angular
.module('app', [])
.controller('ThenCtrl', ThenCtrl);
function ThenCtrl($timeout, $q) {
var vm = this;
vm.items = [];
$q.when(pushA()).then(pushB());
$timeout(pushA, 5000).then(pushB());
function pushA() {
vm.items.push('A');
}
function pushB() {
vm.items.push('B');
}
}
Run Code Online (Sandbox Code Playgroud)
标记
<div ng-app="app">
<div ng-controller="ThenCtrl as vm">
{{vm.items}}
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
我设置了一个小提琴:https://jsfiddle.net/kan3c61t/
angular-promise ×10
angularjs ×10
javascript ×6
promise ×2
q ×2
callback ×1
chaining ×1
http ×1
sequential ×1