【问题标题】:Delay execution of protractor elementArrayFinder.map量角器 elementArrayFinder.map 的延迟执行
【发布时间】:2017-04-05 03:09:12
【问题描述】:

如果您调用量角器 elementArrayFinder 的 map 函数,它将立即在 DOM 中搜索要映射它们的元素,这与 $$ 的行为不同,$$ 等待直到需要子 elementArrayFinder 评估才能找到两者原始元素及其后代。

我需要延迟 map 函数执行的原因是我想在我的测试文件之外的一个文件中预定义它以进行抽象。我目前的尝试是:

Question.array = function(elementArrayFinder) {

  function delayedPromise(executor) {
    this.executor = executor;
  }

  delayedPromise.prototype.then = function(onFulfilled, onRejected) {
    console.log('locating elements');
    return (new Promise(this.executor)).then(onFulfilled, onRejected);
  };

  return new delayedPromise(function(resolve, reject) {
    elementArrayFinder.map(function(omniTask) {
      return new Question(omniTask);
    }).then(resolve, reject);
  });
};

这工作了一段时间,但是当我今天重组测试文件时(不是包含这个函数的文件,这个函数有一段时间没有改变),JavaScript开始出现与这个函数有关的内存问题:

<--- Last few GCs --->

  133580 ms: Mark-sweep 1354.3 (1421.2) -> 1354.3 (1437.2) MB, 2608.1 / 0.0 ms [allocation failure] [GC in old space requested].
  136052 ms: Mark-sweep 1354.3 (1437.2) -> 1354.3 (1437.2) MB, 2471.9 / 0.0 ms [allocation failure] [GC in old space requested].
  138829 ms: Mark-sweep 1354.3 (1437.2) -> 1355.7 (1421.2) MB, 2775.8 / 0.0 ms [last resort gc].
  141436 ms: Mark-sweep 1355.7 (1421.2) -> 1357.0 (1421.2) MB, 2606.6 / 0.0 ms [last resort gc].


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x13c845cfb51 <JS Object>
    1: enqueue [/Users/thasisclaus/omnistack/node_modules/selenium-webdriver/lib/promise.js:~2742] [pc=0x27de9185871b] (this=0x2b9531847931 <an EventEmitter with map 0x17526dabf9e9>,task=0x17b6b944f181 <a Deferred with map 0x17526dac0649>)
    2: addCallback_ [/Users/thasisclaus/omnistack/node_modules/selenium-webdriver/lib/promise.js:~1328] [pc=0x27de919c1a75] (this=0x17b6b944eeb9 <a ManagedPro...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/usr/local/bin/node]
 2: node::FatalException(v8::Isolate*, v8::Local<v8::Value>, v8::Local<v8::Message>) [/usr/local/bin/node]
 3: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/local/bin/node]
 4: v8::internal::Factory::NewFixedArray(int, v8::internal::PretenureFlag) [/usr/local/bin/node]
 5: v8::internal::Handle<v8::internal::TypeFeedbackMetadata> v8::internal::TypeFeedbackMetadata::New<v8::internal::FeedbackVectorSpec>(v8::internal::Isolate*, v8::internal::FeedbackVectorSpec const*) [/usr/local/bin/node]
 6: v8::internal::(anonymous namespace)::EnsureFeedbackVector(v8::internal::CompilationInfo*) [/usr/local/bin/node]
 7: v8::internal::(anonymous namespace)::GenerateBaselineCode(v8::internal::CompilationInfo*) [/usr/local/bin/node]
 8: v8::internal::(anonymous namespace)::GetUnoptimizedCodeCommon(v8::internal::CompilationInfo*) [/usr/local/bin/node]
 9: v8::internal::Compiler::Compile(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Compiler::ClearExceptionFlag) [/usr/local/bin/node]
10: v8::internal::Accessors::FunctionLengthGetter(v8::Local<v8::Name>, v8::PropertyCallbackInfo<v8::Value> const&) [/usr/local/bin/node]
11: v8::internal::PropertyCallbackArguments::Call(void (*)(v8::Local<v8::Name>, v8::PropertyCallbackInfo<v8::Value> const&), v8::internal::Handle<v8::internal::Name>) [/usr/local/bin/node]
12: v8::internal::Object::GetPropertyWithAccessor(v8::internal::LookupIterator*) [/usr/local/bin/node]
13: v8::internal::Object::GetProperty(v8::internal::LookupIterator*) [/usr/local/bin/node]
14: v8::internal::Builtin_Impl_FunctionPrototypeBind(v8::internal::(anonymous namespace)::BuiltinArguments<(v8::internal::BuiltinExtraArguments)0>, v8::internal::Isolate*) [/usr/local/bin/node]
15: v8::internal::Builtin_FunctionPrototypeBind(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/bin/node]
16: 0x27de909092a7
17: 0x27de9185871b
18: 0x27de919c1a75
19: 0x27de919c202c
20: 0x27de912d1b27
21: 0x27de90909895
22: 0x27de912dee53
>> FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
>>  1: node::Abort() [/usr/local/bin/node]
>>  2: node::FatalException(v8::Isolate*, v8::Local<v8::Value>, v8::Local<v8::Message>) [/usr/local/bin/node]
>>  3: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/local/bin/node]
>>  4: v8::internal::Factory::NewFixedArray(int, v8::internal::PretenureFlag) [/usr/local/bin/node]
>>  5: v8::internal::Handle<v8::internal::TypeFeedbackMetadata> v8::internal::TypeFeedbackMetadata::New<v8::internal::FeedbackVectorSpec>(v8::internal::Isolate*, v8::internal::FeedbackVectorSpec const*) [/usr/local/bin/node]
>>  6: v8::internal::(anonymous namespace)::EnsureFeedbackVector(v8::internal::CompilationInfo*) [/usr/local/bin/node]
>>  7: v8::internal::(anonymous namespace)::GenerateBaselineCode(v8::internal::CompilationInfo*) [/usr/local/bin/node]
>>  8: v8::internal::(anonymous namespace)::GetUnoptimizedCodeCommon(v8::internal::CompilationInfo*) [/usr/local/bin/node]
>>  9: v8::internal::Compiler::Compile(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Compiler::ClearExceptionFlag) [/usr/local/bin/node]
>> 10: v8::internal::Accessors::FunctionLengthGetter(v8::Local<v8::Name>, v8::PropertyCallbackInfo<v8::Value> const&) [/usr/local/bin/node]
>> 11: v8::internal::PropertyCallbackArguments::Call(void (*)(v8::Local<v8::Name>, v8::PropertyCallbackInfo<v8::Value> const&), v8::internal::Handle<v8::internal::Name>) [/usr/local/bin/node]
>> 12: v8::internal::Object::GetPropertyWithAccessor(v8::internal::LookupIterator*) [/usr/local/bin/node]
>> 13: v8::internal::Object::GetProperty(v8::internal::LookupIterator*) [/usr/local/bin/node]
>> 14: v8::internal::Builtin_Impl_FunctionPrototypeBind(v8::internal::(anonymous namespace)::BuiltinArguments<(v8::internal::BuiltinExtraArguments)0>, v8::internal::Isolate*) [/usr/local/bin/node]
>> 15: v8::internal::Builtin_FunctionPrototypeBind(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/bin/node]
>> 16: 0x27de909092a7
>> 17: 0x27de9185871b
>> 18: 0x27de919c1a75
>> 19: 0x27de919c202c
>> 20: 0x27de912d1b27
>> 21: 0x27de90909895
>> 22: 0x27de912dee53

我今天更改的测试文件中的上下文是:

fit('Should have the right number of assignment questions initially', function(done) {
      var done = browserHelper.strictDone(done),
          self = this;

      self.communityQuestions = self.myQuestions = [];

      console.log(self.assignmentQuestions.length, self.communityQuestions.length, self.myQuestions.length)

      assignmentPage.assignmentQuestions.then(function(assignmentQuestions) {
        expect(assignmentQuestions.length).toEqual(self.assignmentQuestions.length);

        assignmentPage.communityQuestionsTab.click();

        assignmentPage.communityQuestions.then(function(communityQuestions) {
          expect(communityQuestions.length).toEqual(self.communityQuestions.length);

          assignmentPage.myQuestionsTab.click();

          assignmentPage.myQuestions.then(function(myQuestions) {
            console.log(myQuestions);

            expect(myQuestions.length).toEqual(self.myQuestions.length);

            done();
          });
        });
      });
    });

我不知道这个错误究竟是由函数引起的,还是函数碰巧遇到的一些外部变化。无论如何,我认为可能有更好的方法来延迟地图功能,很可能是直接与 Protractor 的控制流交互。

【问题讨论】:

  • 我们只是将地图、过滤器和其他东西放入页面对象函数中以解决类似情况..
  • 因为在页面对象文件中包含像ageObject.getProperty = function() {return pageObject.previouslyDefinedElementArrayFinder.map(/* args */)} 这样返回地图承诺的函数,而不是像pageObject.property = pageObject.previouslyDefinedElementArrayFinder.map(/* args */) 这样的操作?

标签: javascript protractor


【解决方案1】:

即使我没有返回带有地图的元素(而是返回由元素构造的对象),我认为这与地图挂起的错误有关:https://github.com/angular/protractor/issues/2227

为了解决这个问题,我只是将我的 map 更改为 reduce 并相应地更改了传递的函数,效果很好。

我很确定 map 是更新较少的 elementArrayFinder 迭代函数之一,因为与 reduce 和 lodash 函数不同,map 没有最后一个参数是集合,因此遵循旧的约定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    • 2018-02-25
    • 2011-09-23
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多