File:Node.js logo 2015.svg

7-я нода зарелизилась, ура! Что нового:

  • Движок V8 обновлён до версии 5.4.500.36, в которой обеспечена поддержка 98% возможностей JavaScript, определённых в спецификации ES2015 (ES6) и, частично, будущим стандартом ES2017.
  • Отмечается новый парсер URL, соответствующий стандарту оформления URL, подготовленному сообществом WHATWG.
  • Доработана работа с Buffer, Child Process, Cluster, файловой системой, промисами
  • Полный список изминений

Для меня это долгожданный релиз, так как появилась возможность изпользовать конструкцию async/await без транспайлера babel. Включается это все ключом --harmony.

Теперь можно без babel так:

(async function() {
    let content = await require("request-promise")
                       .get("http://example.com/");
    console.log(content);
})()

Еще неделю назад ветка Node.js 6.x получила статус LTS, обновления для которой будут выпускаться в течение 30 месяцев. Выпуск Node.js 8 запланирован на апрель 2017 года.

Я собрал 7-ю ноду для

Поделиться с друзьями
-->

Комментарии (93)


  1. prog666
    26.10.2016 13:57
    +1

    Я слышал что в v8 54 есть утечка памяти при использовании async await. ждем пока включат 55


    1. rumkin
      26.10.2016 14:04

      Нужны подробности. С чего вы взяли что утечку будут фиксить только в 55 версии? Возможно уже устранили или только в браузере проявляется?



      1. kurtov
        26.10.2016 17:59
        +3

        Release V8 5.5 24 октября (два дня до выхода node 7). В этом релизе представлены async\await функции.
        Баг с утечкой исправлен 16 сентября, v8 5.4 был зарелизен 9 сентября


  1. shasoft
    26.10.2016 14:45
    -1

    А не появилась возможность запускать Node JS с флешки? Штатно, а не с помощью спец-программ.


    1. apelsyn
      26.10.2016 14:54

      Если речь идет о Windows:



  1. justboris
    26.10.2016 15:21
    -6

    Теперь можно без babel так

    Можно, но конкретно так лучше не писать.


    С Promise получается короче:


    require("request-promise")
      .get("http://example.com/")
      .then(content => console.log(content))

    Во-вторых, с инлайновой async-функцией может возникнуть конфуз


    (async function() {
        let content = await require("request-promise")
                           .get("http://example.com/");
        console.log("1");
    })()
    console.log("2");

    В консоли будет


    2
    1

    Что не совсем очевидно при чтении кода, хоть и понятно почему это происходит.


    1. Yeah
      26.10.2016 15:27
      -7

      Касательно последнего примера: разве не в этом суть асинхронности? Честно говоря, меня забавляет, когда нодеры сначала долго рассказывают, как круто, что у них есть асинхроннсость, а потом придумывают костыли типа promises, чтобы таки писать синхронно.


      1. Odrin
        26.10.2016 15:38
        +11

        Promise — это не костыль «чтобы таки писать синхронно», а способ избавиться от callback hell и структурировать асинхронный код.


        1. HelpOP
          26.10.2016 16:35
          +3

          Вы не смотрите в корень проблемы. А конкретно почему возникает callback hell?


        1. apelsyn
          26.10.2016 16:58
          +3

          Покажите мне цикл на промисах, чтоб я асихронно получал пользователя из базы далее что-делал полученными данными и запрашивал следующего пользователя.


          Слабо?


          1. boolive
            26.10.2016 17:05
            -2

            Промисы позволяют применить async/await или генераторы, и получите циклы с виду синхронные.


          1. justboris
            26.10.2016 17:20

            А цикл бесконечный? Как запрашивается пользователь? Если у них id по порядку, то я просто могу пробежаться for-циклом и сделать запрос для каждого id.


            Давайте немного не так: вы приведете пример кода с использованием async-функций, а мы попробуем переписать без него без потери в читаемости.
            UPD. Нашел ваш коммент. Попробую что-нибудь сделать.


          1. seryh
            26.10.2016 17:22
            +2

            Это делается через рекурсию.


            1. apelsyn
              26.10.2016 17:27
              +1

              Напишите аналог на промисах через рекурсию


          1. JustFailer
            26.10.2016 17:23
            -1

            const usersList = getArrayOfUsersSomehow();
            let usersChain = new Promise.resolve();
            
            usersList.foreEach( (user) => {
              usersChain = usersChain
                .then( () => doSomethingWithUser());
            });
            
            

            Что-то подобное? Не спора ради, просто интересно.


            1. apelsyn
              26.10.2016 17:25

              Напишите аналог на промисах, у вас тут "независимая" обработка кажного юзера.


              1. seryh
                26.10.2016 17:38
                +3

                let user,spammers = [];
                (function loop() {
                    getUser().then((user) => {
                        isSpammer(user).then((user) => {
                            spammers.push(user);
                            if (spammers.length <= 10 && user !== null)
                                loop(); 
                        });       
                    });
                }())

                А зачем оно вам? async/await безусловно куда более лучшие инструменты чем promise.


          1. Aries_ua
            26.10.2016 21:21
            +2

            Покажите мне цикл на промисах, чтоб я асихронно получал пользователя из базы далее что-делал полученными данными и запрашивал следующего пользователя.


            В данном предложении содержится просто противоречие. Вы хотите получить пользователей асинхронно, а потом синхронно что-то с ними сделать. Это как? Смысл тогда какой? Асинхронно стоит выбирать, что бы потом, так же что-то с ним сделать. Возможно я не понимаю вашу мысль. Можете более детально расписать? Я тогда сделаю для вас решение.


            1. apelsyn
              26.10.2016 21:27
              +1

              В том то и дело что async/await выглядит как синхронный код а выполняется асинхронно.


              Другими словами когда вы ждете ответа с базы вы не блокируете поток. В этот момент ваше приложение может обрабатвать другие запросы от пользователей.


      1. enniel
        26.10.2016 15:42
        +3

        Только вот с промисами код всё равно не становится синхронным, он остаётся асинхронным, только выглядит получше.


      1. lsknwns
        26.10.2016 16:41
        +2

        Во-первых эти «костыли» никакого отношения к нодерам не имеют, это практически стандарт языка.

        Во-вторых, в стандарт эти «костыли» запиливаются не по желанию тех, о ком вы говорите, а как раз по желанию тех, кто не они, чтобы облегчить им всю тягость бытия вкатывания в язык, ибо как альтернативы нет, а им так сложно разобраться и вообще во всех бедах виноват молоток, а не человек его использующий.

        Собственно если рассматривать под 'нодерами' фанатов языка, то они как раз страдают от лишней перегруженности, которая в общем-то и не нужна (cv. class), потому что 'нефанатам' сложна.


    1. BoryaMogila
      26.10.2016 15:42
      +5

      С промисом короче если у тебя один асинхронный запрос, а если у тебя 2 и больше асинхронных запроса, то на с async/await это:

      (async function() {
          const request = require("request-promise")
          let someData = await request.get("http://example.com/");
          let anotherData = await request.get("http://example2.com/");
          // манипуляции с данными
          console.log(/*результат манипуляций*/);
         
      })();
      

      а с промисом:
      const request = require("request-promise")
      request
        .get("http://example.com/")
        .then((someData) => {
            request
               .get("http://example.com/")
               .then((anotherData) => {
                    // манипуляции с данными
                    console.log(/*результат манипуляций*/);
            })
         }
      

      ничего не напоминает))


      1. justboris
        26.10.2016 15:43
        -1

        Ваш пример лучше. Мой комментарий был про то, что в статье пример использования async-функций высосан из пальца и никакой полезности не показывает.


      1. Yeah
        26.10.2016 16:13

        В вашем примере для await, если каждый запрос выполняется ровно за секунду, то через какое время выполнится console.log?


      1. Galiaf47
        26.10.2016 16:23
        +3

        Извиняюсь если допустил ошибку, но я написал бы немного по другому

        const request = require("request-promise")
        request
          .get("http://example.com/")
          .then((someData) => {
              return request
                 .get("http://example.com/")
          })
          .then((anotherData) => {
            // манипуляции с данными
            console.log(/*результат манипуляций*/);
          }
        


        1. justboris
          26.10.2016 16:27
          +5

          А я бы вообще через Promise.all сделал, чтобы было параллельно


          const request = require("request-promise")
          Promise.all([
            request.get("http://example.com/"),
            request.get("http://example2.com/")
          ]).then(([a ,b]) => {
            console.log(a + b);
          })

          Конечно это сработает, только если второму запросу не нужны данные первого. Если нужны, то async-functions FTW.


        1. brusher
          26.10.2016 17:30
          +1

          Если я не ошибаюсь — вы потеряли someData к моменту манипуляции с данными.
          А вот вариант с Promise.all — в данном случае лучший, если только второй запрос не требует информации из первого :)


      1. bertmsk
        26.10.2016 16:27
        +2

        Это обычный promise hell. Обещали решить с применением политиканов (politicians)


      1. shmidt_i
        26.10.2016 16:39

        const request = require("request-promise")
        request
          .get("http://example.com/")
          .then((someData) => request.get("http://example.com/"))
          .then((anotherData) => {
                      // манипуляции с данными
                      console.log(/*результат манипуляций*/);
              })
           
        

        В этом и смысл — сделать код более плоским


      1. inker
        26.10.2016 16:39
        +1

        Зачем ждать, пока выполнится первый реквест, чтобы запустить второй?

        (async function() {
          const request = require("request-promise")
          const [someData, anotherData] = await Promise.all([
            request.get("http://example.com/"),
            request.get("http://example2.com/")
          ])
          // манипуляции с данными
          console.log(/*результат манипуляций*/);  
        })();
        


        const request = require("request-promise")
        Promise.all([
          request.get("http://example.com/"),
          request.get("http://example2.com/")
        ]).then(([someData, anotherData]) => {
          // манипуляции с данными
          console.log(/*результат манипуляций*/);  
        })
        


        1. walkman7
          26.10.2016 17:24

          Затем что нужны ___последовательные___ запросы (следующий запрос зависит от предыдущего).


          1. apelsyn
            26.10.2016 17:29

            Чтоб не блокировать исполнение других обработчиков. Например к вашему web-серверу пришло несколько запросов.


          1. alek0585
            26.10.2016 18:33

            Возможно ли, что в таком случае имеет место неграмотная архитектура?


            1. VolCh
              27.10.2016 10:05

              Возможно, но возможно и нет. Например, второй запрос должен содержать результаты первого или первый запрос — проверка прав на отправку второго.


            1. Alternator
              27.10.2016 10:39

              Возможно всё

              Но нормальные юзкейсы со строго последовательным асинхронными операциями также существуют:
              1. Операция сейва в редакторе
              — подготовка превью-картинки
              тут может быть параллельно еще какая-то подготовка мета-данных
              — упаковка в архив
              — пересылка на сервер
              — опционально показ красивого(не-alert) модального окна по завершении
              2. массовые операция редактирования/анализа кучи файлов
              в целом операции будут идти параллельно(либо в очереди с заданным лимитом прааллельности)
              но для отдельного файла будет последовательный набор шагов
              — прочитать файл
              — провести изменение/анализ файла
              — записать файл
              3. система макросов для приложения.
              так как некоторые пользовательские операции вынуждены быть асинхронными, то и система макросов становится асинхронными(но строго последовательными)
              Вот тут из моей практики async..await превращает код вообще в песню, по-сравнению с колбеками, или даже чистыми промисами


              1. mata
                30.10.2016 16:24
                -1

                макросы? откуда в js макросы?


                1. staticlab
                  30.10.2016 21:49

                  Имеются в виду не те макросы, которые в Си, а те, которые макрокоманды в прикладных программах.


                1. Alternator
                  31.10.2016 15:10

                  да, подразумевались макрокоманды как в офисе, либо других прикладных программах.

                  но в javascript-е могут быть и макросы как в C
                  1) Вот плагин babel-а, в котором я участвую — https://github.com/codemix/babel-plugin-macros
                  но тут скорее о макросах, как об инлайновых функциях
                  2) Также есть отдельная надстройка синтаксиса — http://sweetjs.org/
                  тут наверно можно гораздо шире определить макросы


      1. Vladimir37
        26.10.2016 16:39

        Нет. С промисами вот так:

        Promise.all([request.get("http://example.com/"), request.get("http://example2.com/")]).then((dataFirst, dataSecond) => {
                // манипуляции с данными
                console.log(/*результат манипуляций*/);
        });
        


      1. neoxack
        26.10.2016 17:21
        -1

        (async function() {
            const request = require("request-promise")
            let someData = await request.get("http://example.com/");
            let anotherData = await request.get("http://example2.com/");
            // манипуляции с данными
            console.log(/*результат манипуляций*/);
        
        })();

        Лучше так:


         let result = await Promise.all([request.get("http://example.com/"), request.get("http://example2.com/") ]);


    1. overherz
      26.10.2016 16:39

      по-моему здесь как раз все очевидно, async/await так и должен работать


      1. justboris
        26.10.2016 16:59
        -1

        Конечно очевидно, если медленно и внимательно читать 5 строчек кода.


        Но представьте, как это будет выглядеть в реальном проекте, где кода больше


        (async function() {
            let content = await require("request-promise")
                               .get("http://example.com/");
           doSomething();
           if(a !== b) {
              doSomethingElse();
           }
        
          // ...
          // и еще много-много кода
          // ...
        
          console.log("1")
        })()
        console.log("2");

        Пока дочитаешь до конца, можно потерять контекст и ошибиться. А с Promise и коллбеками граница синхронного и асинхронного кода четче и понятнее.


    1. apelsyn
      26.10.2016 16:48

      А если в цикле?


      1. justboris
        26.10.2016 17:00

        А можете привести пример кода? Без него непонятно, что вы имеете в виду.


        1. apelsyn
          26.10.2016 17:19

          let user,spammers = [];
          do {
              user = await getUser();
              if (await isSpammer(user)) {
                  spammers.push(user)
              }
          } while (spammers.length <= 10 && user !== null);
          console.log(spammers)

          Ну и все это, конечно, внутри асихронной функции.


          1. justboris
            26.10.2016 17:33

            function collectSpammers(spammers) {
               if(spammers.length > 10) {
                 return spammers;
               }
               return getUser()
                 .then(user => {
                   if(!user) {
                     return spammers;
                   }
                   return isSpammer(user).then(spammer => {
                      if(spammer) {
                         spamers.push(users);
                      }
                      return spammers;
                   });
                 })
                 .then(() => collectSpammers(spammers))
            }
            
            collectSpammers([]).then(spammers => console.log(spammers))

            Согласен, получилось не так аккуратно как с async, но ведь реализуемо! Сомневаюсь, что нужно писать такой код регулярно, и поэтому async так уж необходим в стандарте


            1. f0rk
              26.10.2016 17:58

              Если spammers.length <= 10 && user == null он вроде бы продолжит выполняться


              1. justboris
                26.10.2016 18:05

                Почему вы так считаете? Есть же проверка сразу после getUser.


                1. f0rk
                  26.10.2016 18:11

                  getUser().then(u => { if (!u) return spammers }) Зарезолвится с массивом spammers, потом вы вызываете .then(() => collectSpammers(spammers)), и процесс зациклился, пока getUser() возвращает null следующий в цепочке then будет вызывать collectSpammers


                  1. justboris
                    26.10.2016 18:17

                    Действительно, спасибо за замечание! Поправил:


                    function collectSpammers(spammers) {
                       if(spammers.length > 10) {
                         return spammers;
                       }
                       return getUser().then(user => {
                         if(!user) {
                           return spammers;
                         }
                         return isSpammer(user)
                           .then(spammer => {
                             if(spammer) {
                               spamers.push(users);
                             }
                             return spammers;
                           })
                           .then(() => collectSpammers(spammers));
                       })
                    }
                    
                    collectSpammers([]).then(spammers => console.log(spammers))


                    1. f0rk
                      26.10.2016 18:52

                      Ок, раз уж пошла такая пьянка, добавлю свой вариант :)

                      function collectSpammers(n) {
                        const spammers = [];
                        
                        return Array(n).fill(0).reduce(m => m
                          .then(() => getUser()
                            .then(function check(u) {
                              if (u === null) return Promise.reject();
                              
                              return isSpammer(u).then(spammer => { 
                                if (spammer) spammers.push(u);
                                else return getUser().then(check);
                              });
                            })), Promise.resolve()).then(() => spammers, () => spammers);
                      }
                      
                      collectSpammers(10).then(spammers => console.log(spammers));
                      


                      1. inook
                        28.10.2016 14:38

                        function collectSpammers(_users) {
                          return _users.reduce((promise, _user) => {
                            return promise.then((prevUsers = []) => {
                              const user = User.findById(_user);
                              return Promise.all([...prevUsers, user]);
                            })
                          }, Promise.resolve());
                        };
                        


                        1. apelsyn
                          28.10.2016 15:12

                          User.findById синхронный?


                          1. inook
                            28.10.2016 15:38

                            Mongoose Model#findById возвращает Promise если не передан callback


                        1. f0rk
                          28.10.2016 19:47

                          Тут немного другая задача решается


            1. apelsyn
              26.10.2016 18:06
              +1

              А если вам нужно проверить не случилось ли ошибки при получении данных из базы
              try {
              user = await getUser();
              } catch (err) {
              // Error handling
              }
              Вы представляете во что превратиться Ваш код?


              async/wait это отличная конструкция для написания человек-читаемого и легко понимаемого кода. Потому что код выглядит как синхронный а виполняется асинхронно.


              Ваше заявление "С Promise получается короче" работает только для примитивных конструкций, для более сложных это не всегда справедливо


              1. justboris
                26.10.2016 18:12

                А если вам нужно проверить не случилось ли ошибки при получении данных из базы
                Вы представляете во что превратиться Ваш код?

                Примерно в то же самое, во что и ваш. Добавится пара конструкций.


                Ваше заявление "С Promise получается короче" работает только для примитивных конструкций

                Согласен. Но в статье вы привели именно такую конструкцию, на что я и обратил внимание. Чтобы показать хорошие стороны async можно было сразу привести пример про спаммеров, а не тривиальный request.


              1. kurtov
                26.10.2016 18:39

                let spammers = [];
                
                getUser()
                    .catch(onGetUserErrorHandler)
                    .then(getSpammer)
                    .then(() => console.log(spammers));
                
                function getSpammer(user) {
                
                    if (user === null) {
                        return;
                    }
                
                    if (spammers.length === 10) {
                        return;
                    }
                
                    return isSpammer(user)
                        .then((isSpammer) => isSpammer && spammers.push(user))
                        .catch(onSpammerCheckErrorHandler)
                        .then(getUser)
                        .catch(onGetUserErrorHandler)
                        .then(getSpammer);
                }
                



                1. indestructable
                  26.10.2016 20:18

                  then после catch не правильно, если, конечно, не хотите попасть в оба.


                  1. kurtov
                    27.10.2016 09:21

                    если возникнет ошибка с одним юзером, то перейдем к следующему, а не завершим работу


          1. alek0585
            26.10.2016 18:42

            ```
            var user, spammers = [];

            function load () {
            return getUser().then(function (user) {
            if (isSpammer(user)) {
            spammers.push(user);
            }
            return user;
            });
            }
            var array = _.map(_.range(0, 10), function () {
            return load;
            })
            utils.sequence(array).then(function () {
            console.log(spammers);
            });
            ```


  1. enniel
    26.10.2016 15:39

    Для debian-based дистрибутивов можно установить так:

    curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
    sudo apt-get install -y nodejs
    

    Доку пока ещё не обновили, может и под другие дистрибутивы уже можно установить.


    1. asdf404
      26.10.2016 17:52

      Ещё можно использовать NVM:

      nvm install v7.0.0
      nvm alias default v7.0.0
      


      1. iShatokhin
        27.10.2016 08:03
        +1

        Можно даже так (если фиксирование минорной версии не критично):


        nvm install v7 // поставится последняя доступная v7
        nvm alias default v7 // дефолтной всегда будет самая свежая из установленных 7-ок, не нужно будет постоянно подправлять минорные версии после обновления


      1. saggid
        27.10.2016 19:34

        Скажите пожалуйста, как вы решаете проблемы с nvm и подобными библиотеками для установки библиотек, когда например ты установил своему пользователю какую-то версию node.js, а потом из под банального sudo {cmd} эта нода уже недоступна? Та же проблема с rvm, к примеру. Или другой случай: надо запускать по крону какой-то баш скрипт, которому тоже эта Node.js нужна. Там тоже обычно приходится немного извращаться, подключая в начале скрипта нужные файлы из папки nvm.


        Ставить глобально через какой-нибудь apt по-моему удобнее всё-таки, чем таким образом. Хотя и менее гибко.


        1. asdf404
          27.10.2016 19:50

          Ни разу не приходилось запускать node с sudo за время использования nvm, а до этого приходилось лишь пару раз. Но, если бы пришлось, то скорее всего прописал бы полный путь до бинарника (sudo ~<username>/.nvm/versions/node/<version>/bin/node). Да, неудобно, но если это не разовый запуск (например крон), то можно создать симлинк в /usr/bin или создать алиас или скрипт:


          #!/path/to/node
          
          console.log('Hello World!')

          Сейчас вообще стараюсь не запускать проекты на хост-машине напрямую. Толкаю всё в докер, а с хост машины дёргается docker-compose exec some-periodic-task node /src/task.js — криво, неудобно, но лучше не придумал.


          1. saggid
            28.10.2016 03:23

            Неудобен такой подход, с прямой ссылкой на какой-то бинарник node.js в nvm. Обновишь ноду — и все скрипты исправлять свои? :) Если идти такой дорогой, то к баш-скрипту лучше подключать код загрузки .nvm из .bashrc:


            export NVM_DIR="/home/{username}/.nvm"
            [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"  # This loads nvm

            Тогда будет загружаться текущая активная Node.js.




            Возвращаясь к глобальной установке установщиков библиотек. На тему Node.js я могу сам за себя ответить, ибо нашёл способ установить nvm глобально на машине:


            wget -qO- https://raw.githubusercontent.com/xtuple/nvm/master/install.sh | sudo bash


            Но блин. В мире-то не только NVM существует… Для каждой библиотеки такой форк искать на гитхабе? :) В общем, для себя я пока ничего лучше какого-то свеженького ppa или последнего дистрибутива своей ОС не нашёл.


            1. ChALkeRx
              28.10.2016 04:37
              +1

              xtuple/nvm

              Эм. Вообще-то, апстрим creationix/nvm, зачем вы устанавливаете старый форк какой-то компании?


              В nvm было довольно много изменений с тех пор.


              1. saggid
                28.10.2016 04:56

                Ну дык будьте хоть немножечко более внимательны, я достаточно разъяснил всё в своём сообщении. Это не просто форк, а изменённый инсталлер. Почитайте хоть описание к нему, написано же всё.


              1. saggid
                28.10.2016 05:01

                В чём вы только правы — это вполне возможно что nvm будет очень старый, да. Я думал, этот скрипт как-то подтягивает последний nvm и устанавливает его глобально.


  1. boolive
    26.10.2016 15:39
    +1

    import/export когда будет?


    1. bromzh
      26.10.2016 16:06
      +1

      А в стандарте уже прописано, как резолвить пути в этих операторах? Т.е. если мы напишем:


      import { foo } from 'foo';
      import { bar } from './bar';

      откуда будут импортированы эти объекты?


      С require всё понятно — это чисто нодовская функция, она завязана на систему модулей ноды и node_modules.


      Но стандарт ecma не должен завязываться на какую-то конкретную реализацию и должен как-то предусмотреть различные платформы. Ведь в браузере "нет node_modules".


      1. lucky_libora
        26.10.2016 16:18

        гугл на одном из недавних выступлений сказали, что пока этого в движке V8 нет


        1. bromzh
          26.10.2016 23:06

          Так а разве в стандарте есть описание (хотя бы черновик) того, как именно нужно будет резолвить модули? Пока определились только с синтаксисом импортов/экспортов. А пока стандарта нет, в движок нечего добавлять.


          1. lsknwns
            26.10.2016 23:25
            +1

            https://whatwg.github.io/loader/


            1. bromzh
              26.10.2016 23:30

              Спасибо!


      1. indestructable
        26.10.2016 16:28

        Резолвить по тем же правилам, что и пути в require. Сделали бы хоть простейшую поддержку в виде трансформации в require/module.exports.


        1. bromzh
          26.10.2016 23:28
          +3

          Можно, конечно, включить это в ноду напрямую. Люди начнут писать под ноду программы, используя нативные импорты (т.е. в npm-пакет попадёт не common-модуль (с require и module.exports), а es6-модуль с import/export).


          А потом примут стандарт, и окажется, что резолв модулей как в require не совсем совместим с принятым стандартом. Что тогда делать? Уже написанные программы не будут работать на новых версиях ноды, новые программы не будут работать на тех версиях ноды, где была неправильная нативная поддержка модулей. Представьте, как весело станет управлять зависимостями, если часть из них написаны по-старой схеме, часть по-новой.


          Именно для этого и есть babel. Добавить или удалить плагин в бабеле просто, а вот менять версию ноды уже тяжелее. Когда ситуация с модулями прояснится, тогда и нужно будет начинать внедрять, но не раньше.


        1. VolCh
          27.10.2016 10:14
          +1

          Для трансформаций есть babel, он хорошо делает свою работу, зачем дублировать эту функциональность в Node.js, при том, что с большой вероятностью её потом нужно будет выпиливать?


          1. indestructable
            27.10.2016 11:07

            Да в том-то и дело, что хотелось бы без babel. Он, конечно, крутой, но все-таки отсутствие компиляции круче, чем самая крутая компиляция.


            1. VolCh
              27.10.2016 14:20

              Сделали бы хоть простейшую поддержку в виде трансформации в require/module.exports.


              А это не компиляция будет?


              1. indestructable
                27.10.2016 17:35

                Технически, конечно, компиляция (или интерпретация). Компьютеры пока не научились джаваскрипт исполнять непосредственно, поэтому, совсем без компиляции/интерпретации не обойтись, очевидно :)


                Я имел ввиду компиляцию джаваскрипта перед запуском на Node.


  1. AndreyRubankov
    26.10.2016 16:32
    +2

    Понимаю, что сейчас будут дико минусовать карму, но: Зачем?((

    1. Зачем вводить функционал до того, как он появится в стандарте (это еще draft на es2017)?
    2. Зачем вводить async/await на уровне языка, учитывая, что это всего лишь сахар для промисов?
    вот завтра окажется, что «async/await» — это плохо, а поддерживать эту фичу придется до конца жизни ES.


    1. staticlab
      26.10.2016 16:47

      1. Ну так реализована экспериментальная поддержка в движке v8. В самой ноде активируется только по ключу --harmony.


      2. Цель — избавиться от promise hell.


      1. AndreyRubankov
        26.10.2016 17:10

        Цель благородная, но я к тому, что завтра появится async/await hell и быть беде. Если Promise API можно просто выкинуть и забыть (заменить на что-то новое), то async/await из спецификации уже не выкинешь.

        Мой поинт о том, что не стоит вносить на уровень языка фичи главная цель которых сделать код красивее.


        1. serf
          26.10.2016 17:15
          -1

          Мой поинт о том, что не стоит вносить на уровень языка фичи главная цель которых сделать код красивее.

          Хороший поинт, инженерный подход, но к сожалению вся суть развития EcmaScript относится к "деланию кода красивее", в отличии от допустим TypeScript.


        1. dimaaan
          26.10.2016 23:17

          async await впервые появился в c# в 2012 году и за 4 года не заработал себе плохой репутации.
          да и вообще, как вы себе представляете async/await hell?
          можно пример?


          1. AndreyRubankov
            27.10.2016 08:27

            > как вы себе представляете async/await hell?

            Как жуткое хитросплетение синхронных и асинхронных функций.
            Как асинхронные функции, которые будут отдаваться наружу как результат выполнения
            … и await await func() как следствие.
            Как асинхронные функции в качестве параметров для тех же промисов или еще чего-то.

            — проблема все та же = незнание как написать хорошо, порождает hell.

            > async await впервые появился в c# в 2012 году и за 4 года не заработал себе плохой репутации.

            Я могу ошибаться, но проблем с этим подходом не на много меньше, чем с обычным многопоточным программированием, просто эти проблемы сделали неявными.
            Все те же await await func() и манипуляции с контекстом.

            Да эти все «минные тропы» уже через месяц проходятся довольно просто, но не стоит забывать, что месяц — это у хорошего специалиста, который уже познал горя с многопоточностью.

            Да и в C# вам множество тулов поможет и подскажет где вы не правы. В то время, как в ES это можно будет узнать только в рантайме и порою даже только на продакшене.

            ps: я за развитие языка, но я против добавления Сахара ради сахара.


            1. Alternator
              27.10.2016 10:26

              Хотелось бы узнать больше об этих минных тропах.
              с обычными callback-ами мне доводилось сталкиваться с тремя проблемными анти-патернами:
              1) асинхронная функция содержит некоторое количество синхронного кода
              если он упадет, асинхронная функция никогда не вернет результата.
              весьма пакостный для отладки случай.
              — чистые промисы решают эту проблему не полностью, если использовать их как попало
              2) асинхронная функция делает что-то еще после вызова callback
              — странно что-то делать после того как вернул результат.
              — этим что-то может оказаться повторный вызов callback(например сразу после if-а), что приводит к двойному старту последующего кода
              — но для этой ошибки есть правило в eslint)
              — промисы решают эту проблему
              3) асинхронная функция вызывает callback на самом деле синхронно(например данные из кэша)
              — может порождать дивные стектрейсы в случае падения в колбеке(захватится уже «выполненная» функция не имеющая отношения к падению)
              — при попытке решать первую проблему try..catch-ами, приводит ко второй проблеме — err-callback будет вызван еще раз
              — логика сложнее в отладке, так как нарушен контракт
              — промисы решают эту проблему

              Использование async..await автоматически фиксит все 3 проблемы, даже не допуская возможности так ошибиться
              И единственный встреченный минус: стектрейсы при отладке все еще не синхронные)
              Ну и дополнены обертками от babel

              Поэтому интересуют какие проблемы сохранили/создали async..await-ы?
              Особенно в контексте того что, в C# есть способы ранней проверки анти-патернов.
              Я бы с удовольствием написал бы пару правил для статического анализа в eslint


    1. apelsyn
      26.10.2016 16:53

      Это не драфт, предложение находится в Stage 3 ("Candidate"), в следующем месяце будет частью стандарта Stage 4 ("Finished").


    1. alibertino
      26.10.2016 16:59

      Потому что, по сути, это единственный путь рождения и проверки немертворожденных стандартов. А по поводу поддержки, это не обязательно, можно объявить deprecated. Поэтому и запускается не в LTS-версии.


  1. ChALkeRx
    27.10.2016 13:14
    +4

    Node.js 7.0.0 зарелизился. Встречайте async/await без babel

    Включается это все ключем --harmony.

    Эээ. Напомню ещё раз: --harmony в продакшне использовать не стоит, и привязываться к его фичам — тоже.


    Пока что рекомендованный способ сделать себе async/await — это таки babel.


    98% возможностей JavaScript, определённых в спецификации ES2015 (ES6)

    Это и в v6 LTS было. Причём отставшиеся 2% — PTC.