Pull to refresh

Comments 28

Итераторов и генераторов пока нету?
Прочитал недавно всю спецификацию — в целом язык понравился.
Правда, создалось ощущение, что полезен он будет только в режиме «полного цикла» — то есть когда на нем пишется большой проект, целиком от начала до конца.
Писать на нем, например, библиотеку общего назначения вроде как бессмысленно.
Ну для библиотеки как раз это имеет большой смысл в двух аспектах: проектирование API и выставление его наружу с подсказками для редактора через .d.ts.

Вот пример ребят из Wix: blogs.msdn.com/b/typescript/archive/2015/03/17/guest-post-gil-amran-talks-about-using-typescript-at-wix.aspx. Внутренние функции хоть на голом JS, а на стыках TS.
Про .d.ts знаю, но это для других пользователей TS.
А я другое имел в виду: писать на TS библиотеку, которую потом будут использовать разные люди, пишущие в других окружениях (ванильный JS, CS, LS и пр). В этом случае особо большого смысла не видно.
Если к библиотеке идёт .d.ts файл, это сильно облегчает её понимание. Это так, на всякий случай.
Почему же, очень практично. Исходный код библиотеки будет на TS со всеми плюшками, а все остальные могут использовать скомпилированный js-вариант. Примерно так команды Angularjs \ Ember \ остальных фреймворков и работают.
Я может быть не в тему. Я видел в ts репозитории issue на добавление типов числе переменной длины (i8 — int8, uint, int и тд). Не знаете, планируется что нибудь такое добавить. Понятно, что это здоровенный костыль в js, но сделало бы типобезопасную работу проще с битовыми операциями.
И я даже очень понимаю насколько это не популярно, и может понадобится весьма не часто. Но просто реальных альтернатив я не нашел, самое близкое это asm.js — но его руками не напишешь.
Почему костыль? Разработчики на JS уже давно используют типизацию на полную катушку.
Там где есть необходимость.

Вот тут можно ознакомиться с фундаментом: Typed Array.
Есть полно библиотек которые добавляют сахару (удобства) использования.

asm.js, кстати, тоже через них работает.
Костыль потому что в яваскрипте самом нет такой типизации. А что я хочу я думаю лучше объяснить на примере:

let a: int8 = 150
let b: int8 = 200

Я хочу чтобы в результате было для
a | b
(a | b) & 0xFF
var a, b, c, typed;
typed = new Uint8Array(new ArrayBuffer(2));
typed[0] = 150;
typed[1] = 200;
typed[2] = 300; // # undefined. Only 2 bytes allocated

a = typed[0] | typed[1]; // 222
b = (typed[0] | typed[1]) & 0xFF; // 222 ?
c = parseInt(d, 16); // 546

Оно?

Не совсем понимаю что вы хотите получить в результате.
Да, оно! Я честно говоря не думал, о таком использовании typed arrays. Спасибо хорошая идея.
На здоровье (:

По опыту добавлю небольшой TL;DR.

— Читайте доки начиная с MDN. Там ИМО лучше всего.
ArrayBuffer — просто определяет кусок памяти в байтах
TypedArray (Uint8Array/Uint16Array/...) — просто предоставляет доступ к этим байтам в каком-то формате. Мы как бы говорим JS как их читать. Cast view, так сказать.
DataView — мне не понравился чем-то. Вроде как новый стандарт, который не взлетел.

Вот как можно использовать. Внимание, СoffeScript (не люблю скобочки и ";")

# Создаем рандомный binary.
module.exports.getRandomBuffer = (mb = 1) ->
    buffer = new ArrayBuffer(mb * 1024 * 1024 )
    i8 = new Int32Array(buffer)

    i = 0
    while i < i8.length
        i8[i] = Math.random() * 100 | 0
        i++

    return buffer

# Считаем тупой но быстрый хеш:
module.exports.noobHash = (arg) ->
    i8 = new Int32Array(arg)
    hash = 0
    i = 0
    while i < i8.length
        hash += i8[i]
        i++
    return hash
Теперь ждём async/await.
Хотя и с промисами хорошо идёт.
А зачем вам async/await? Просто самому приходится постоянно иметь делать с асинхронностью и я не понимаю проблемы/потребности.
Это не совсем ответ. Вот быстрый рефактор.

fs.readdir source, (err, files) ->
    if err then console.log 'Error finding files: ' + err; return 

    files.forEach (filename, fileIndex) ->
        console.log filename
        gm(source + filename).size (err, values) ->
            if err then console.log 'Error identifying file size: ' + err; return

            console.log filename + ' : ' + values
            aspect = values.width / values.height

            widths.forEach (width, widthIndex) =>
                height = Math.round(width / aspect)
                console.log 'resizing ' + filename + 'to ' + height + 'x' + height
                @resize(width, height).write destination + 'w' + width + '_' + filename, (err) ->
                    if err then console.log 'Error writing file: ' + err


А вообще тут вполне можно разделить вещи на отдельные функции и все.
async/await тут не помогут
А теперь нормальный, читаемый код:
try {
    await fs.readdir(source, defer files);

    await files.forEach(defer filename, defer fileIndex);

    console.log(filename)

    await gm(source + filename).size(defer values);

    console.log(filename + ' : ' + values)
    aspect = (values.width / values.height)

    await widths.forEach(defer width, defer widthIndex);

    height = Math.round(width / aspect)
    console.log('resizing ' + filename + 'to ' + height + 'x' + height)

    await this.resize(width, height).write(destination + 'w' + width + '_' + filename, defer _);

} catch (e) {
    console.log(e);
}

Теперь понятней. Спасибо.
Лично для меня он менее читаем, но это скорее всего привычка.
Действительно, у такого подхода, во многих ситуациях есть потенциал.

Вот еще равнозначный код:
source
try
    fs.readdir source, (files) ->
        files.forEach (filename, fileIndex) ->
            console.log filename
            gm(source + filename).size (values) ->
                console.log filename + ' : ' + values
                aspect = values.width / values.height

                widths.forEach (width, widthIndex) =>
                    height = Math.round(width / aspect)
                    console.log 'resizing ' + filename + 'to ' + height + 'x' + height
                    @resize(width, height).write destination + 'w' + width + '_' + filename
catch (e)
    console.log e



Еще для таких вещей хорошо себя зарекомендовала библиотека async

Вот код из одного проекта для инициализации RabbitMQ

source
async.series [
    async.apply channel.assertQueue.bind(channel), 'magic1', queueProps
    async.apply channel.assertQueue.bind(channel), 'magic2', queueProps
    async.apply channel.assertQueue.bind(channel), 'magic3', queueProps
    async.apply channel.assertQueue.bind(channel), 'magic4', queueProps
    async.apply channel.assertExchange.bind(channel), 'magix', 'direct', {}
    async.apply channel.bindQueue.bind(channel), 'magic1', 'magix', 'route1', {}
    async.apply channel.bindQueue.bind(channel), 'magic2', 'magix', 'route2', {}
    async.apply channel.bindQueue.bind(channel), 'magic3', 'magix', 'route3', {}
    async.apply channel.bindQueue.bind(channel), 'magic4', 'magix', 'route4', {}
], (err, res) =>
    @checkForErr 'broker err', err 
    if !err?
        @onBrokerReady()

Это ошибочный код. Исключения у вас не ловятся.

Более красивая и каноничная версия async/await есть в ES7, но она совместима только с Promise.
С опозданием благодарю за разъяснения и наводку на такой подход.
Нашел кучу библиотек которые таким занимаются. Пока немного сыровато, но в в общем у такого подхода есть много положительных нюансов.
Вы читерите немного. Перепишите на чистом JS (function function function function!, хотя тут в TS тоже есть сахарок со стрелочкой, хоть и не равнозначный), и добавьте полноценную обработку исключений из колбэков — тогда сравнение будет равноценным.

Promise/deferred проблему решают, но с await все же намного короче и читаемее.

Кофескрипт же справедливее будет сравнивать с IcedCoffee.
В ES6 уже тоже есть стрелочки, так что не совсем чит. Все коллеги что из JS уже пишут в ES6 стрелочками и ок.
Тут только скобочек нет, всего навсего.

Await & ICS хорошие. ICS действительно делает много финтов ушами, особенно там, где это связано с циклами.
Приятно. Однако в работе я бы пока этого не использовал.
UFO just landed and posted this here
Я правильно понимаю, что с реализацией ES6 modules можно забыть про ад с ///<reference>? Если так — это просто супер.
Я правильно понимаю, что ES6-модули можно будет компилировать как в виде внутренних модулей а-ля "///reference" (тупо последовательное слияние файлов), так и в виде внешних(RequireJS, CommonJS, pure ES6)?
Похоже, так.

TypeScript supports down-level compilation of external modules using the new ES6 syntax.

When compiling with -t ES3 or -t ES5 a module format must be chosen using -m CommonJS or -m AMD.

When compiling with -t ES6 the module format is implicitly assumed to be ECMAScript 6 and the compiler simply emits the original code with type annotations removed.

(https://github.com/Microsoft/TypeScript/issues/2242)

Насчет последовательного слияния не очень понятно, но не очень-то и надо, для этого есть gulp (или grunt, если кому нравится больше).
Sign up to leave a comment.