All streams
Search
Write a publication
Pull to refresh
161
1.5
Send message
выставлять заголовок content-length и много чего еще.

Не обязательно, так как с HTTP/1.1 поддерживается 'Transfer-Encoding': 'chunked', который node.js выставляет автоматически.
А если будет еще nginx с включенным gzip, то Content-Length заранее и вовсе нет смысла высчитывать, так как nginx всё равно удалит его и поставит 'Transfer-Encoding': 'chunked'.

но до полноценного сервера нужно сделать много чего еще

По сути полноценный сервер это вот:
const http = require('http')

http.createServer((req, res) => {
  let html = 'hello<br>world'
  res.writeHead(200, {
    'Content-Type': 'text/html; charset=utf-8',
  })
  res.end(html)
}).listen(8080)


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

Поэтому в общем-то у автора уже полноценный сервер с нужными ему удобствами, и даже тот участок, где require в try-catch по сути не проблема, так как уже успешные require nodejs закэширует, и производительность не упадет.

В целом согласен с вашим комментарием, для быстрого/надежного развертывания экспресс или коа лучше подходят, это да.
Просто хорошо, что появляются статьи, которые расширяют понимание ноды дальше экспресса.
Ого, не знал что редактор лежит отдельно и его можно легко встроить на страницу
Да нее, будет «ReferenceError: patams is not defined» в любом случае, даже если без 'use strict' запускать

Единственное что, если без 'use strict' запускать, можно записать какое-нибудь значение в необъявленную переменную, она в глобальную область видимости попадет, но само по себе undefined не подставится
Да, это массив промисов, через рест параметр они вливаются в общий массив промисов, которые потом вызываются параллельно
Это ведь JavaScript, конечно может. Или не JavaScript?
Так и есть, мой промах, не учел что этот кусок кода в условии, которое может никогда не выполнится
нет – со стороны выглядит будто вы этот кусок вырезали из кода
Как раз наоборот, код сократил раза в 3, а все переменные переименовал, чтобы легче смысл передать
И Остапа понесло…

Ну и он страно написан – await Promise.all(bricks)
bricks — это набор функции, которые возвращают промис.
Это модули, которые делают только свою маленькую работу, все они запускаются параллельно и их результат складывается в единый результат, а дальше в шаблонизаторе, уже в зависимости от наличия модуля будет активирован или нет нужный кусок шаблона

Ну заменили вы .then на await. Вроде как стало на один уровень вложености меньше, но стоит вам добавить обработку исключений и все вернестя на свои места.
В данном случае, обработка исключений одна единственная на более высшем уровне (на точке входа), на каждом этапе она не требуется

>А когда она требуется, то просто делается все через Promise.all
Если вас не затруднит, проилюстрируйте свою идею кодом — по, возможности, перепишите код из этого комментария
Вот этот пример: https://habrahabr.ru/company/ruvds/blog/326074/#comment_10167050

Но если вам нужен именно пример моего изначального примера:
Заголовок спойлера
async function gogogo(queryList) {
    let resultJson = {}
    let promiseList = []
    let rawDataPromiseList = []

    for (const query of queryList) {
        let json = {}
        const type = await getType(query)

        if (type === 1) {
            promiseList.push(getJson(query))
        }
        else if (type === 2) {
            rawDataPromiseList.push(getRawData(query))
        }
        else {
            break
        }
    }

    for (const rawData of await Promise.all(rawDataPromiseList)) {
        promiseList.push(rawToJson(rawData))
    }

    for (const json of await Promise.all(promiseList)) {
        Object.assign(resultJson, json)
    }

    return resultJson
}

И из цикла выйдем, и все запросы пойдут конкурентно, максимально насколько возможно в рамках данного примера. И даже больше, легко добавим более сложные условия:
        const type = await getType(query)
        const subtype = await getSubType(query)

        if (type === 1 && subtype === 4) {
            promiseList.push(getJson(query))
        }
        else if (type === 2 && !subtype) {
            rawDataPromiseList.push(getRawData(query))
        }
        else if (subtype === 1) {
            break
        }

Ну тоесть вы серьезно думаете, что кусок кода с необъявленной переменной может скомпилироваться?
Фраза «упрощенный пример» о чем нибудь говорит?
Все эти примеры выдуманы, чтобы показать упрощение синтаксиса, но вы зацепились за конкурентность

По сути, обычно следующий запрос может зависит от ответа предыдущего, а иногда и сразу от двух предыдущих запросов, поэтому конкурентность не требуется. А когда она требуется, то просто делается все через Promise.all

Вот упрощенный пример из рабочего проекта:
const [userdata, params] = await Promise.all([getUserData(), getParams()])
let bricks = []

if (params.allowedExtraData && userdata.needExtraData) {
    userdata.extraData = await getExtraData(userdata.id)
}

bricks.push(...params.bricksForModule[userdata.moduleType])
bricks.push(...params.bricksForType[params.mainType])

if (params.groups[userdata.groupType].isModerator) {
    bricks.push(...patams.templatesModerator)
}

const bricksData = await Promise.all(bricks)
...

И дальнейшая обработка результатов
Вот этот вариант мне нравится
Я про то и говорю:
Всё становится очень хрупким и нужно всю цепочку держать в голове, чтобы небольшие изменения внести. При этом никто не говорит, что это не возможно, возможно-то возможно
Достаточно чуть усложнить условие (приложение в процессе динамического развития, много экспериментов):

        const type = await getType(query)
        const subtype = await getSubType(query)
        if (type === 1 && subtype === 4) {
            json = await getJson(query)
        }
        else if (type === 2 && !subtype) {
            const rawData = await getRawData(query)
            json = await rawToJson(rawData)
        }
        else if (subtype === 1) {
            break
        }

И всё становится чуточку сложнее и нужно поломать голову, как это впихнуть в промисы без промисс-хелла.
И я уверен, что это получится сделать, но я не уверен, что можно это сделать за 10 секунд, как это делается на async-await

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

Нее, мы обсуждаем фичу которая нативно работает в node, и во всех актуальных браузерах, кроме Edge и Opera Mini
http://caniuse.com/#feat=async-functions

как-то это не логично чуть-чуть(точно не continue)
но ок:

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

Всё становится очень хрупким и нужно всю цепочку держать в голове, чтобы небольшие изменения внести. При этом никто не говорит, что это не возможно, возможно-то возможно
Тогда понятно, да
О том и речь, понадобился функционал сторонней библиотеки

А вот это я с трудом представляю как изобразить, чтобы такой вариант заработал:
  return getRawData(query)
    .rawToJson(rawData)

При то, что и getRawData и rawToJson асинхронные функции. Либо тут надо быть гуру промисов, чтобы в этом разобраться

Но даже при этом всё равно получилось не то же самое, так как «return {}» не тоже самое что «break», и в случае с map перебор продолжится, а в моей случае предпологался выход из цикла
Можно-то можно, даже callback-hell можно переписать и превратить во что-то приятное и понятное

Но вот такое:
async function gogogo(queryList) {
    let resultJson = {}

    for (const query of queryList) {
        let json = {}
        const type = await getType(query)
        
        if (type === 1) {
            json = await getJson(query)
        }
        else if (type === 2) {
            const rawData = await getRawData(query)
            json = await rawToJson(rawData)
        }
        else {
            break
        }

        Object.assign(resultJson, json)
    }

    return resultJson
}

async function doSomething() {
    const resultJson = await gogogo(queryList)
    const html = templateGenerator(resultJson)
    console.log(hmtl)
}

doSomething()

Уже становится немного сложновато представить на промисах, особенно если какой-то еще логики надо добавить
В данном случае даже опаснее доверять выводу writeln, так как:
import std.stdio;

void main() 
{
	double a = 0.1;
	double b = 0.2;
	if(a + b == 0.3) {
		writeln(true);
	}
	else {
		writeln(false);
	}
}

> false

Да и в целом в любом языке так, все случае не предугадаете, когда будет 0.3, а когда 0.3000000001
Поэтому в любом случае стоит делать проверку на диапазон или любой другой хак.
golang:
package main
import "fmt"

func main() {
	var a float32 = 0.1
	var b float32 = 0.1
	fmt.Println(a * b)
	b = 0.9
	fmt.Println(a * b)
}

> 0.010000001
> 0.089999996
Вот вы и сами подтвердили что ваш тест говно
https://habrahabr.ru/post/323208/#comment_10103096

Information

Rating
1,468-th
Registered
Activity