Pull to refresh
54
0
Егор @termi

User

Send message
Не буду спорить, не изучал вопроса про аппаратное ускорение, хотя гугл говорит, что аппаратное ускорение для webm (без лицензионных отчислений) было заявлено ещё в 2011 году. Если у вас есть ссылка на статью о текущей ситуации поделитесь пожалуйста.

В любом случае, если мы не собираемся открывать тяжеловесное видео в FullHD, а также много маленьких видео на одной вкладке, я не вижу особого профита от аппаратного ускорения. Тем более, что внедрение webm таким популярным сервисом подстегнуло бы производителей побыстрее внедрять аппаратную поддержку этого формата (если этого до сих пор нету), что сказалось бы положительно на веб-индустрии в целом.
Странный выбор формата видео, с учётом того, что браузеров поддерживающих webm больше, чем поддерживающих mp4.
Более того, уже существующие форматы webp и apng умеют анимацию, лучше бы направили усилия на популяризацию этих форматом (для того, чтобы их побыстрее внедрили в основные браузеры), чем на придумывания нового «формата» (который и не формат вовсе).
Если вы таки будете улучшать обработку событий, то сделайте поддержку handleEvent, чтобы можно было избежать использования функции Function#bind
Решением для IE может быть копирование всех методов из прототипа в экземпляр в конструкторе CustomArray и в методах «concat», «reverse», «slice», «splice», «sort», «filter», «map». Из минусов можно выделить то, что не будет работать оператор instanceof.
Учтите, что этот вариант не работает в IE меньше 11го, т.к. в этих IE не поддерживается __proto__
Можно было бы добавить пару строк про await/async из es7, т.к. их трансляция в генераторы тривиальна.
> а Rx уведомляет о новом доступном элементе (push).
А можно пример, как использовать возможности push в трансдьюсерах?
Просто примеры в статье, например
reduce([1, 2, 3, 4, 5, 6, 7], first5T(append), []);    // => [1, 2, 3, 4, 5]

демонстрируют законченные операции над множеством.
Допустил опечатку в коде: done должен быть объявлен вне цикла do-while.
Полностью правильный код
function * gen1(collection, limit = NaN) {
    let counter = 0;
    for ( let item of collection ) {
        yield `item is ${ item }`;

        if ( ++counter >= limit ) break;
    }
}


function * gen2(...collections) {
    for ( let collection of collections ) {
        yield * collection;

        if ( (yield 'end collection') == true ) break;
    }
}

let test = gen2( gen1([1, 2, 3, 4, 5, 6, 7], 3), [5, 6, 7], gen1(['a', 'b', 'c']), new Array(999).join('1|').split('|') );
let counter = 0, sendValue = void 0;
let value, done;

do {
    ({value, done}) = test.next(sendValue);

    if ( value == 'end collection' ) {
        if ( ++counter > 2 ) sendValue = true;
    }
    else console.log(value);
}
while( done != true );


Код работающий в FireFox
function * gen1(collection, limit = NaN) {
    let counter = 0;
    for ( let item of collection ) {
        yield 'item is ' + item;

        if ( ++counter >= limit ) break;
    }
}


function * gen2(...collections) {
    for ( let collection of collections ) {
        yield * collection;

        if ( (yield 'end collection') == true ) break;
    }
}

let test = gen2( gen1([1, 2, 3, 4, 5, 6, 7], 3), [5, 6, 7], gen1(['a', 'b', 'c']), new Array(999).join('1|').split('|') );
let counter = 0, sendValue = void 0;
let value, done;

do {
    ({value, done}) = test.next(sendValue);

    if ( value == 'end collection' ) {
        if ( ++counter > 2 ) sendValue = true;
    }
    else console.log(value);
}
while( done != true );

Если честно, то не вижу существенных преимуществ перед генераторами. За исключением некоторых деталей, на генераторах можно делать аналогичные вещи:
1. Преждевременное завершение обработки коллекции как внутри генератора (по логике или с помощью посылаемого в генератор значения), так и снаружи — для цикла for-of это break, в остальных случаях просто перестаём вызывать у генератора next
2. Генераторы и компания, работают с любыми коллекциями, главное, чтобы они реализовывали Iterator Protocol
3. Генераторы умеют «выдавать для одного элемента несколько новых (прим. flatten)» — yield * iterator переключит вызываемый код на итерацию по iterator, а когда iterator закончится, вызывающий код вернётся в оригинальный генератор.

Хотелось бы узнать мнение автора поста о генераторах в сравнении с Трансдьюсерами, т.к. я больше использую генераторы, поэтому для меня они более понятны, а автор несомненно хорошо разбирается в Трансдьюсерах и может сравнить эти две технологии.

Пример с генераторами:

function * gen1(collection, limit = NaN) {
    let counter = 0;
    for ( let item of collection ) {
        yield `item is ${ item }`;

        if ( ++counter >= limit ) break;
    }
}


function * gen2(...collections) {
    for ( let collection of collections ) {
        yield * collection;

        if ( (yield 'end collection') == true ) break;
    }
}

let test = gen2( gen1([1, 2, 3, 4, 5, 6, 7], 3), [5, 6, 7], gen1(['a', 'b', 'c']), new Array(999).join('1|').split('|') );
let counter = 0, sendValue = void 0;

do {
    let {value, done} = test.next(sendValue);

    if ( value == 'end collection' ) {
        if ( ++counter > 2 ) sendValue = true;
    }
    else console.log(value);
}
while( done != true );

Вживую
habrahabr.ru/post/237613/#comment_7992463
Второй блок кода с Generator Comprehension — тут неявный yield
Я, например, использую трансляцию «на лету» (конечно, для продакшена, лучше странслировать всё на этапе сборки проекта):

код:
var es6transpiler = require('es6-transpiler');

// node_inject_on перехватывает вызовы require и транслирует es6-код в es5
es6transpiler.node_inject_on(function(fileName){
	return fileName.endsWith(".es6.js");
});

require("./main.es6.js");// запускаем программу написанную на es6

es6transpiler.node_inject_off();

Можно, а иногда и нужно (чтобы не ловить браузерные баги) использовать трансляторы.
Сейчас есть целых три на выбор (каждый со своими достоинствами и недостатками):
* Traceur от Google (Наиболее полная поддержка es6, развивается Гуглом)
* esnext (Активно развивается, большое комьюнити, часть кода развивается facebook'ом)
* es6-transpiler (Трансляция строчка-в-строчку, простой и производительный выходной код)
Спасибо за статью. Интересно будет почитать следующую часть про _.take.
Но если рассматривать без возможных оптимизаций _.take, то, по-моему всё слишком переусложнено.
Я бы написал проще:
let coll = [1, 2, 3, 4];
let addOne = (x) => x + 1;
let filterFn = (x) => x < 4;
coll = [ for (item of coll) if ( filterFn(item = addOne(item)) ) item ];

Конечно, мой способ решает 1ю и 4ю проблемы лишь частично, т.к. результат Array Comprehension — это всегда массив, а если coll будет не массивом, то для прохода по нему объект должен реализовывать Iterator Protocol. Но во-первых, возвращение объекта из массивной операции, я считаю неправильным, а во-вторых, для того, чтобы работать с кастомными коллекциями, можно использовать простой цикл for-of, который тоже работает с Iterator Protocol.

Для ленивой работы, можно преобразовать Array Comprehension в Generator Comprehension:
coll = ( for (item of coll) if ( filterFn(item = addOne(item)) ) item );

coll.next();


Опять же, мой способ имеет достоинства и недостатки. Достоинства это то, что используются стандартные средства языка, и четко объявляется результат операции — массив или генератор (в случае же использования цикла for-of код тоже тривиален). Существенным недостатком, конечно, является то, что нету простой возможности реализовать что-то типа оптимизации вызова функции _.take.
— возможность открывать новую вкладку рядом с текущей.

+1. Для меня это самая приоритетная «хотелка»
Но, чтобы только так как в 12й Опере — т.е. чтобы был выбор:
* открыть «в конце очереди» (в Opera 12 — клик средней кнопки мыши по пустому месту в панели вкладок)
* открыть вслед за текущей (в Opera 12 — включается в настройках и работает по нажатию на крестик и Ctrl+T)
Некоторые замечания по выбору картинки для закладки:

1. https://ru.wikipedia.org/wiki/Новости_(телесериал,_США)
Нужная картинка на страницы есть, но её нельзя выбрать в меню добавления закладки
скриншот
image

2. https://ru.wikipedia.org/wiki/Джонсон,_Линдон
Нельзя выбрать позиционирование длинного изображения, из-за этого не получается воспользоваться наиболее подходящей картинкой.
скриншот
image
Object.defineProperty(Function.prototype, 'myFunction', {enumerable: false, value: function(){ /* do something cool */ }})
Благодаря использованию enumerable:false, этот способ не является опасным, в отличие от Function.prototype.myFunction=function(){}

Да и не так страшно расширение прототипов стандартных объектов, как его малюют, главное подходить с умом.
> кстати, что за синтаксис такой?
Если вы про ObjectLiteral то это es6. Есть про handleEvent — то это стандартный обработчик, определённый в стандарте addEventListner'а developer.mozilla.org/en-US/docs/Web/API/EventListener

>> .throttle(200)
> Простите, что это за метод? ES5/6?
Практически «стандартное» расширение прототипа функции, которое есть во многих библиотеках. Например sugarjs.com/api/Function/throttle
Похоже на вашу функцию procrastinate, которая, кстати, тоже не заработает с этой библиотекой.

>> Библиотека не заработает в IE7
> В статье говорится о восьмом осле
В описании гиста написано:
Simple addEventListener polyfill for IE7 and IE8

>> Вероятно библиотека вызовет утечки памяти в IE8, т.к. ссылка на элемент сохраняется в скоупе обработчика события.
> Мне нечего возразить. Ослы «славятся» своей очисткой памяти от мусора. Постараюсь от этого избавиться.
Моя версия полифила, хотя и громоздкая, но практически не вызывает утечек памяти. Конечно, полностью от утечек избавится не удалось, но минимизировать их удалось.
Хочу добавить несколько слов про addEventListener:
1. Приведённая в статье библиотека — это не полифил, как бы автор её не называл, т.к. она не реализует функционал addEventListener'ра.
1.1. Библиотека не умеет handleEvent:
let application = {
    name: 'test',
    handleEvent() { console.log(this.name) }
}
document.addEventListener('click', application);

1.2. Библиотека не умеет «захват» событий
1.3. Библиотека не заработает с любым отложенным исполнением обработчика события в IE8, т.к. в IE объект event «очищается» сразу после вызова обработчика:
document.addEventListener('mousemove', function(event) {
    console.log(event.type);// В IE8 тут будет ошибка
}.throttle(200));


2. Библиотека не заработает в IE7, во первых потому что в IE7 нету window.Element, а во вторых, потому что window.Node (который можно использовать вместо window.Element) — это не js-объект/конструктор, и его prototype не распространяет свои свойства на потомков.

3. Вероятно библиотека вызовет утечки памяти в IE8, т.к. ссылка на элемент сохраняется в скоупе обработчика события.
var asyncSupported = false;
try {
  asyncSupported = typeof (new Function('return async function(){ }')) === 'function'
}
catch(e){}
Регуляркой проверить наличие await/async в коде будет гораздо проще, чем проверить многи другие конструкции языка. Тем более, что async всегда идёт перед function, а await перед CallExpression. Ну или воспользоваться esprima (найти только ветку или форк, который поддерживает await/async).

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Works in
Date of birth
Registered
Activity