我正在构建一个复杂的混合应用程序并且已经在真实设备上进行测试。偶尔,我从Angular那里得到了可怕的$digest already in progress
错误 - 特别是,它似乎是在一个有点长的消化周期之后。从堆栈跟踪看来,它似乎是从更新location.href的Angular defer函数启动的,然后触发fastclick以发送touchend,而touchend又触发导致错误的第二个摘要。有没有人遇到过同样的错误 - 如果有的话,你是怎么解决它的?
对于那些感兴趣的人,这是我在stacktrace中看到的:
Error: [$rootScope:inprog] $digest already in progress
http://errors.angularjs.org/1.3.0/$rootScope/inprog?p0=%24digest:
file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:80:32
beginPhase@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:14473:31
$apply@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:14220:21
file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:22523:29
eventHandler@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:3013:25
dispatchEvent@sendClick@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/fastclick/fastclick.js:295:30
onTouchEnd@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/fastclick/fastclick.js:589:18
file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/fastclick/fastclick.js:105:43
url@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:5022:19
setBrowserUrlWithFallback@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:11080:21
file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:11186:40
$eval@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:14123:28
$digest@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:13939:36
file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:14161:33
completeOutstandingRequest@file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:4877:15
file:///private/var/mobile/Containers/Bundle/Application/4040564A-5631-4A1A-B2FD-6E53F9A574F2/test.app/www/js/3rdparty/angular/angular.js:5250:33
答案 0 :(得分:4)
这是破坏者(source link):
// other considerations:
//
// you might read 1 char at a time. this can simplify
// your loop, possibly easier to debug
// ... would you have to detect and remove eoln? i.e. '\n'
// ... how would you handle a bad input
// such as not hex char, odd char count in a line
//
// I would probably prefer to use getline(),
// it will read until eoln(), and discard the '\n'
// then in each string, loop char by char, creating char pairs, etc.
//
// Converting a vector<uint8_t> to char bytes[] can be an easier
// effort in some ways. A vector<> guarantees that all the values
// contained are 'packed' back-to-back, and contiguous in
// memory, just right for binary stream output
//
// vector.size() tells how many chars have been pushed
//
// NOTE: the formatted 'insert' operator ('<<') can not
// transfer binary data to a stream. You must use
// stream::write() for binary output.
//
std::stringstream ssOut;
// possible approach:
// 1 step reinterpret_cast
// - a binary block output requires "const char*"
const char* myBuff = reinterpret_cast<const char*>(&myBytes.front());
ssOut.write(myBuff, myBytes.size());
// block write puts binary info into stream
// confirm
std::cout << "\nConfirm6: ";
std::string s = ssOut.str(); // string with binary data
for (size_t i=0; i<s.size(); ++i)
{
// because binary data is _not_ signed data,
// we need to 'cancel' the sign bit
unsigned char ukar = static_cast<unsigned char>(s[i]);
// because formatted output would interpret some chars
// (like null, or \n), we cast to int
int intVal = static_cast<int>(ukar);
// cast does not generate code
// now the formatted 'insert' operator
// converts and displays what we want
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< intVal << " ";
}
std::cout << std::endl;
//
//
return (0);
} // int t194(void)
问题是人工FastClick.prototype.sendClick = function(targetElement, event) {
// ... some lines skipped
clickEvent = document.createEvent('MouseEvents');
clickEvent.forwardedTouchEvent = true;
targetElement.dispatchEvent(clickEvent); // got you!
};
的处理程序将立即解雇(demo)。这通常很好 - 但不适用于Angular,因为click
事件已在touchEnd
阶段内生成,而$digest
似乎对其必须处理的事件有些乐观ng-click
代码。因此$apply
ka-boom。
无论如何,这件事似乎很容易解决:只是异步事件发送!一种相当直接的方法是用{...}替换$digest
行。
got you!
至少在我们的案例中似乎有效。 )