2015-06-30 8 views
1

Я создаю массив, который выполняется асинхронно (для удовольствия). Это прекрасно работает:Внутреннее * текущее значение * массива

class AsyncArray extends Array { 
    constructor() { 
     super(); 
     this.x = 0; 
    } 

    [Symbol.iterator]() { 
     return { 
      next:() => { 
       let promise = new Promise(resolve => setTimeout(
        () => resolve(this.x++), 1000) 
       ); 
       return {done: this.x >= this.length, value: promise}; 
      } 
     }; 
    } 
} 

async() => { 
    for (let x of AsyncArray.of(1, 2, 3)) { 
     let value = await x; 
     console.log(value); 
    } 
}(); 

Однако это печатает 0...1...2, потому что я отслеживание текущего счетчика самостоятельно и инициализирую его x.

Есть ли способ получить текущий итератор значение внутренний массив? Я также должен был бы иметь возможность правильно определить значение done.

+0

ли Вы хотите решить с помощью 'x' или 'это [х]'? – Bergi

+0

@Bergi с использованием 'this [x]' имеет смысл и решает проблему. –

+0

Упс, похоже, я не понял ваш вопрос, я думал, что ваша проблема в том, что вам пришлось использовать пользовательский счетчик ... – Bergi

ответ

5

Я думаю, вы не хотите, чтобы счетчик был встроен в ваш массив, а скорее на ваш итератор. Используйте локальную переменную в методе, что:

[Symbol.iterator]() { 
    var x = 0; 
    return { 
     next:() => { 
      let promise = new Promise(resolve => 
       setTimeout(() => resolve(this[x++]), 1000) 
      ); 
      return {done: x >= this.length, value: promise}; 
     } 
    }; 
} 

Самый простой способ, чтобы написать итераторы, хотя это с помощью функции генератора:

[Symbol.iterator]*() { 
    for (var x = 0; x < this.length; x++) 
     yield new Promise(resolve => 
      setTimeout(() => resolve(this[x]), 1000) 
     ); 
} 

Это будет заботиться о правильном done значения, а (и не будет "return" обещание, которое разрешается с undefined).


Альтернатива, которая бы полностью избежать отслеживания состояния в переменной или экземпляре собственности локальной будет использовать стандартный итератор массива:

[Symbol.iterator]() { 
    var vals = super[Symbol.iterator](); 
    var it = Object.create(Object.getPrototypeOf(vals)); // an array iterator 
    it.next =() => { 
     var res = vals.next(); 
     if (!res.done) 
      return {done: false, value: new Promise(resolve => 
       setTimeout(() => resolve(res.value), 1000) 
      )}; 
     return res; 
    }; 
    return it; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^