我在$ timeout内有一段代码,执行了一个Promise。当我为此编写单元测试时,我使用$ timeout.flush()并且可以进入$ timeout块。然后解决了promise(因为$ timeout在内部调用了$ scope。$ apply()),但是在方法代码完成并冒出茉莉花之后,我得到了错误TypeError:无法读取未定义的属性'$$ nextSibling'。其他人曾经经历过吗?
控制器代码:
$scope.timeoutFunction = function(){
$timeout(function () {
$scope.callFunction().then(function () {
callAnotherFunction();
});
}, 0);
}
Run Code Online (Sandbox Code Playgroud)
单元测试代码:
$scope.timeoutFunction();
scope.$digest(); // not needed
$timeout.flush(); // even tried $timeout.flush(0);
Run Code Online (Sandbox Code Playgroud)
另外,如果我模拟超时是一个回调函数,它的工作原理。例:
function mockedTimeout() {
arguments[0]();
}
$timeout = mockedTimeout;
Run Code Online (Sandbox Code Playgroud)
然后,我们只使用$ scope。$ digest来调用promise,超时立即运行。可能是尖角虫吗?
完整的错误堆栈:
TypeError: Cannot read property '$$nextSibling' of undefined
at n.$get.n.$digest (http://localhost:51679/referenceFile?path=D:\development\Projects\WebSite\Scripts\Libs\Angular\angular.min.js:124:101)
at n.$get.n.$apply (http://localhost:51679/referenceFile?path=D:\development\Projects\WebSite\Scripts\Libs\Angular\angular.min.js:126:293)
at Object.fn (http://localhost:51679/referenceFile?path=D:\development\Projects\WebSite\Scripts\Libs\Angular\angular.min.js:139:3)
at Function.angular.mock.$Browser.self.defer.flush (http://localhost:51679/referenceFile?path=D:\development\Projects\WebSite\Scripts\TDD\angular-mocks.js:127:42)
at Function.angular.mock.$TimeoutDecorator.$delegate.flush (http://localhost:51679/referenceFile?path=D:\development\Projects\WebSite\Scripts\TDD\angular-mocks.js:1732:28)
at null.<anonymous> (http://localhost:51679/Tests.js:254:18)
at jasmine.Block.execute (http://localhost:51679/referenceFile?path=D:\development\Projects\WebSite\Scripts\jasmine.js:1064:17)
at jasmine.Queue.next_ (http://localhost:51679/referenceFile?path=D:\development\Projects\WebSite\Scripts\jasmine.js:2096:31)
at jasmine.Queue.start …Run Code Online (Sandbox Code Playgroud) 我对Angular JS deferred和$ q感到困惑.我发现这个SO问题解释了$q.defer()和之间的区别.$q解释说
$ q.reject是创建延迟的快捷方式,然后立即拒绝它
所以$q.reject()必须等于
var deferred = $q.defer(); deferred.reject()如果没有请解释两者之间的实际差异.
但在我的情况下,$q.reject()是工作,但deffered.reject()不工作.我们也需要退回被拒绝的承诺,$q.reject()但不是deferred.reject().我看过没有回报的例子deffered.reject()
这是代码
var deferred = $q.defer();
myService.getData()
.then(function(response){
deferred.notify('Just a notification');
deferred.reject('rejected');
})
.then(function(response) {
console.log('done');
}, function(response) {
console.log('rejected');
})
Run Code Online (Sandbox Code Playgroud)
这不起作用,但是当我替换deferred.reject时$q.reject(),承诺被拒绝并且控制被移动到随后的块的错误函数.
任何帮助是极大的赞赏.提前致谢.
以下方法工作:
$q.when()
.then(checkCookieToken) // check if cookie already exists e.g. in cookie
.then(setHeader) // set Header with REST-Token e.g from cookie
.then(checkTokenOnline) // if not OK logout
.then(getMenu) // if previous OK get navigation menu
.then(getDataResource) // set ngResource
.then(getData); // and query it
Run Code Online (Sandbox Code Playgroud)
4个问题:
1)如果eg checkTokenOnline不正常,我不想执行其余的功能,我怎么能退出(退出,中断,等等......)?
2)如何设置其中一些并行,其中一些是串行的?
3)如何在它们之间传输数据?
4)如何使以下功能取决于之前的结果?
我仍然无法理解使用 $q 服务的作用,(它究竟会添加什么)如果你想创建一个只需要通过 http 调用一个 API 的服务,在这种情况下我不知道为什么应该'我只是执行以下操作(不使用 $q):
this.getMovie = function(movie) {
return $http.get('/api/v1/movies/' + movie)
.then(
function(response) {
return {
title: response.data.title,
cost: response.data.price
});
},
function(httpError) {
// translate the error
throw httpError.status + " : " +
httpError.data;
});
};
Run Code Online (Sandbox Code Playgroud) 我是Angular的新手,我正在测试一个运行API级别服务的Angular服务,该服务将大量调用包装到REST服务中.因为它正在处理HTTP请求,所以服务的两个部分都在使用promises,它似乎工作正常,但我无法对承诺的行为进行任何测试.
我的服务代码的相关部分(非常简化)如下所示:
angular.module('my.info')
.service('myInfoService', function (infoApi, $q) {
infoLoaded: false,
allInfo: [],
getInfo: function () {
var defer = $q.defer();
if (infoLoaded) {
defer.resolve(allInfo);
} else {
infoApi.getAllInfo().then(function (newInfo) {
allInfo = newInfo;
infoLoaded = true;
defer.resolve(allInfo);
});
}
return defer.promise;
}
});
Run Code Online (Sandbox Code Playgroud)
当我设置我的模拟时,我有这样的事情:
describe("Info Service ",
function() {
var infoService, infoRequestApi, $q;
beforeEach(module("my.info"));
beforeEach(function() {
module(function($provide) {
infoRequestApi = {
requestCount: 0,
getAllInfo: function() {
var defer = $q.defer();
this.requestCount++;
defer.resolve( [ "info 1", "info 2" ] );
return …Run Code Online (Sandbox Code Playgroud) 我在这里遇到角度2的麻烦。我使用返回承诺的服务,但是当我尝试检索响应时出现错误。
我读过这个问题, 这是我的代码。
这是HotelService.ts
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
//rxjs promises cause angular http return observable natively.
import 'rxjs/add/operator/toPromise';
@Injectable()
export class HotelService {
private BASEURL : any = 'http://localhost:8080/hotel/';
constructor(private http: Http) {}
load(): Promise<any> {
return this.http.get(this.BASEURL + 'api/client/hotel/load')
.toPromise()
.then(response => {
response.json();
//console.log(response.json());
})
.catch(err => err);
}
}
Run Code Online (Sandbox Code Playgroud)
此Hotel.ts(组件)
import { Component, OnInit } from '@angular/core';
import { NavController } from 'ionic-angular';
import { HotelService } from …Run Code Online (Sandbox Code Playgroud) 我需要进行api调用,以返回ID和与其关联的值的响应。然后,promise解析并返回true或false(如果找到或未找到查询的id)。
我怎样才能做到这一点?使用诺言的新手。正如诺言似乎令人困惑
这是使用API的终点,UserService返回ID和薪水的数组。我需要检查ID是否存在以及薪水是否与查询匹配,然后Promise需要解析为true或false。
这是身份证和收入的对象
[{
"id": 1,
"name": "Primary",
"sal": [{
"id": "1",
"sal": "10"
}, {
"id": "2",
"sal": "20"
}]
},{
"id": 2,
"name": "Secondary",
"sal": [{
"id": "1",
"sal": "100"
}, {
"id": "2",
"sal": "200"
}
]
}];
UserService.hasUserValue(id, income).then(function(qualifiesforlowIncome){
var isLowIncome = qualifiesforlowIncome
}
Run Code Online (Sandbox Code Playgroud)
qualifyforlowIncome是返回true或false的布尔值。我正在使用角度,因此在这种情况下我应该执行$ q.defer并返回defer.promise吗?
对此还不太清楚
我将替换$http为Fetch API,然后将其替换$q为Promise API。因此,Angular不再运行摘要循环,因此UI无法呈现。为了解决这个问题,我尝试了Zone.js,这似乎可以部分解决我们的问题。不幸的是,其API在0.6中已完全更改,因此我们使用的是旧版0.5.15。
现在到实际问题了。
刷新页面时,Angular会按预期进行配置和引导应用程序。在这个阶段,我初始化区和装饰$rootScope.apply用区和$rootScope.$digest()。现在,当我在状态/路由(使用ui-router)之间进行转换时,一切都按预期工作,但是当完全刷新时,就会出现竞争状况,并且区域/摘要无法正确运行。我不确定如何解决。
我在angular.run()块中包含以下代码:
console.log('Zone setup begin');
const scopePrototype = $rootScope.constructor.prototype;
const originalApply = scopePrototype.$apply;
const zoneOptions = {
afterTask: function afterTask() {
try {
$rootScope.$digest();
} catch (e) {
$exceptionHandler(e);
throw e;
}
}
};
scopePrototype.$apply = function $applyFn() : void {
const scope = this;
const applyArgs = arguments;
window.zone.fork(zoneOptions).run(() => {
originalApply.apply(scope, applyArgs);
console.log('Zone + $digest run!');
});
};
console.log('Zone setup end');
Run Code Online (Sandbox Code Playgroud)
在上方可以看到我在区域初始化开始,结束和运行时(+ …
javascript angularjs angularjs-http angular-promise fetch-api
我能够成功执行Promise.all,并且优雅地处理解析和拒绝.但是,有些承诺会在几毫秒内完成,有些可能/可能需要一段时间.
我希望能够为Promise.all中的每个promise设置超时,因此它可以尝试最多花费5秒.
getData() {
var that = this;
var tableUrls = ['http://table-one.com','http://table-two.com'];
var spoonUrls = ['http://spoon-one.com','http://spoon-two.com'];
var tablePromises = that.createPromise(tableUrls);
var spoonPromises = that.createPromise(spoonUrls);
var responses = {};
var getTableData = () => {
var promise = new Promise((resolve, reject) => {
Promise.all(tablePromises.map(that.rejectResolveHandle))
.then((results) => {
responses.tables = results.filter(x => x.status === 'resolved');
resolve(responses);
});
});
return promise;
};
var getSpoonData = () => {
var promise = new Promise((resolve, reject) => {
Promise.all(spoonPromises.map(that.rejectResolveHandle))
.then((results) => {
responses.tables = results.filter(x …Run Code Online (Sandbox Code Playgroud) 我有一个启动异步进程X的函数F。该函数返回一个诺言,当X结束时将解决该诺言(我是通过X返回的诺言来学习的)。
在运行X的第一个实例X1时,可能会有更多的F调用。每个调用都会产生X的新实例,例如X2,X3,依此类推。
现在,这是困难所在:创建X2时,根据X1的状态,X1应该结束或中止。仅当X1不再处于活动状态时,X2才应开始工作。无论如何,从先前所有对F的调用返回的未解决的承诺也应仅在X2结束后才能解决-或者,如果X在运行时再次调用F,则在X的任何后续实例中也应解决。
到目前为止,对F的第一个调用将调用$q.defer()创建一个deferred,所有对F的调用将返回其承诺,直到最后一个X结束为止。(然后,应解析延期,并将保留该延期的字段重置为空,等待下一个对F的调用。)
现在,我的问题是等待所有X实例完成。我知道,$q.all如果我事先拥有X实例的完整列表,便可以使用,但是由于我不得不考虑以后对F的调用,因此这不是解决方案。理想情况下,我应该-将then某些东西链接到X返回的诺言中,以解决延迟的问题,并在将其链接到X的后续实例后立即“解除链接”该功能。
我想像这样的事情:
var currentDeferred = null;
function F() {
if (!currentDeferred) {
currentDeferred = $q.defer();
}
// if previous X then "unchain" its promise handler
X().then(function () {
var curDef = currentDeferred;
currentDeferred = null;
curDef.resolve();
});
return currentDeferred.promise;
}
Run Code Online (Sandbox Code Playgroud)
但是,即使那是正确的解决方案,我也不知道如何执行“解除链接”。
我该怎么办?我是否错过了一些常见的模式,甚至没有内置的Promise功能,还是完全走错了路?
要添加一些上下文:调用F以(异步)加载数据并更新一些可视输出。F返回一个承诺,仅当视觉输出再次更新到稳定状态(即没有其他更新待处理)时才应解决。
angular-promise ×10
angularjs ×9
javascript ×7
promise ×2
unit-testing ×2
angular ×1
bluebird ×1
cancellation ×1
es6-promise ×1
fetch-api ×1
ionic2 ×1
jasmine ×1
timeout ×1
undefined ×1