LINUX.ORG.RU

Зачем нужны promises?

 


0

3

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

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

Пункт в) успешно решается замыканиями, т.е. futures тут не при делах. А как по остальным пунктам? Что-то не могу слёту понять, можно ли тут получить какую-то пользу. Или я ещё что-то упустил?

★★★★★

Ну вот когда я в нодке два запроса делаю и мне надо дождаться, пока оба закончатся, но я их не хочу последовательно пускать, как без промисов-то?

amomymous ★★★
()

Promise — это всего лишь способ не свихнуться когда используешь коллбэки. Хочешь подробнее — смотри в одном из тысячи разжёвывающих примеров с JS (поскольку они заметно облегчают callback hell там) либо в питоновом deferred из twisted (потому, что в JS они слизаны именно оттуда). Ну или в java, но это не так весело.

x3al ★★★★★
()
Ответ на: комментарий от anonymous

Promise это не конструкция, что бы ты под этим не подразумевал.

In computer science, future, promise, and delay refer to constructs used for synchronization in some concurrent programming languages.

https://en.wikipedia.org/wiki/Futures_and_promises

Если по-простому, то promise это то, куда помещается результат тем, кто его вычисляет, а future - это то, откуда он забирается тем, кому он нужен.

asaw ★★★★★
()
Последнее исправление: asaw (всего исправлений: 2)

тебя точно анонiмоус не кусал?

qnikst ★★★★★
()

Я сперва подумал, что у тебя анонимус аккаунт угнал :)

На последовательном запуске действительно вложенных замыканий может хватить. Проблема начинается, когда надо запустить много действий одновременно и дождаться результата от каждого. И тут нужны либо библиотеки типа async (для JS), либо промисы.

Дальше дело вкуса - кому что больше нравится.

Vit ★★★★★
()

Ты какой-то фантазер по ходу. Хоть бы википедию читанул для приличия, прежде чем бред нести.

newquestion
()
Ответ на: комментарий от Vit

И тут нужны либо библиотеки типа async (для JS), либо промисы.

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

Deleted
()
Ответ на: комментарий от Vit

надо запустить много действий одновременно
для JS

А ты в курсе, что JS однопоточен? Как ты можешь запустить много одновременно? И причем тут промисы вообще? Ты бухой чтоли? Или с рождения такой?

newquestion
()
Ответ на: комментарий от asaw

Если по-простому, то promise это то, куда помещается результат тем, кто его вычисляет, а future - это то, откуда он забирается тем, кому он нужен.

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

newquestion
()
Ответ на: комментарий от Deleted

Ну если есть встроенные барьеры - нивапрос.

Vit ★★★★★
()
Ответ на: комментарий от Deleted

Да то про что он говорит, это и есть типа барьера, к промисам как таковым это не имеет отношения. Есть такая функция Promise.all(promises).then(...) ее просто прилепили к конструктору, «для приличия», с таким же успехом она могла быть Foo.all или просто all. Она имеет к промисам лишь то отношение, что в качестве аргумента принимает массив обещаний. То есть примерно такое же, как функция map к массивам.

newquestion
()

В основном промисы нужны чтоб не рвать визуально поток выполнения.

Всё, остальное просто бонусы.

ya-betmen ★★★★★
()
Последнее исправление: ya-betmen (всего исправлений: 1)
Ответ на: комментарий от newquestion

А ты в курсе, что JS однопоточен?

А браузер нет

Как ты можешь запустить много одновременно?

for(var i = 0; i < 100; i++){
    $.getScript(i + '.js');
}
ya-betmen ★★★★★
()
Ответ на: комментарий от ya-betmen

for(var

Это 100% последовательный код по определению. Его одновременным не назовешь ни с какой, вообще, точки зрения.

anonymous
()

избавиться от цепочки сообщений

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

anonymous
()
Ответ на: комментарий от ya-betmen

Ты хотел сказать, асинхронные, видимо. Но речь шла не об этом, а о каком-то мифическом «одновременном запуске»

anonymous
()
Ответ на: комментарий от ya-betmen

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

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

anonymous
()
Ответ на: комментарий от anonymous

Отмотай наверх и смотри на какой пост ты отвечал про однопоточность жаваскрипта.

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

ya-betmen ★★★★★
()
Последнее исправление: ya-betmen (всего исправлений: 1)
Ответ на: комментарий от x3al

Promise — это всего лишь способ не свихнуться когда используешь коллбэки. Хочешь подробнее — смотри в одном из тысячи разжёвывающих примеров с JS (поскольку они заметно облегчают callback hell там) либо в питоновом deferred из twisted (потому, что в JS они слизаны именно оттуда).

Я уже один из тысячи посмотрел и не понял. В чём именно наступает облегчение?

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Trust for what, you ask? Whether you realize it or not, you are implicitly trusting someAsyncThing(..) for the following:

  • Don’t call my callback too early
  • Don’t call my callback too late
  • Don’t call my callback too few times
  • Don’t call my callback too many times
  • Make sure to provide my callback with any necessary state/parameters
  • Make sure to notify me if my callback fails in some way

http://blog.getify.com/promises-part-1/ )

Там многое применительно к JS, но уже реализовать все пункты этого списка на коллбэках — нетривиально.

x3al ★★★★★
()
Ответ на: комментарий от anonymous

чтобы строить асинхронные цепочки сообщений

А я вот в tcl без всяких промисов строю цепочки сообщений. Просто назначаю «замыкание» на обработчик событий. Что я делаю не так?

и избавиться от представлений о стеке.

А зачем избавляться от представления о стеке? Мне наоборот без стека туго, потому что он сразу показывает много информации об истории выполнения и структуре программы, и ещё по нему можно бросить исключение и поставить try - finally. Цепочку сообщений же нужно распутывать, чтобы понять логику, это ручная работа. try - finally на цепочку поставить нельзя.

P.S. я не пытаюсь спровоцировать драку, я действительно не понимаю. Это бывает :)

den73 ★★★★★
() автор топика
Ответ на: комментарий от ya-betmen

Ты че реально чтоли альтернативный? Ты можешь отличить одновременный запуск от одновременного выполнения? Тема, которую ты *поддержал* она вообще дебильна от самого начала. Твой цикл, и одновременость/неодновременность запуска к примисам вообще никакого отношения не имеют, никто не запрещает им запускаться в разное время, от этого конечный итог, *барьера* не измениться. Вы со своим друганом просто, тупо, банально слышали звон, да не знаете, где он.

var promises = []

var makePromise = function(){return new Promise(function(r){setTimeout(r, 10, 1)})}

setTimeout(function(){promises.push(makePromise())}, 1)
setTimeout(function(){promises.push(makePromise())}, 10)
setTimeout(function(){promises.push(makePromise())}, 100)

setTimeout(function(){
  Promise.all(promises).then(function(values){console.log(values)})
}, 1000)


//[ 1, 1, 1 ]

Вот тебе «разновременный запуск». Что нибудь изменилось? И при чем тут твой сраный цикл, понять не возможно вообще, на*я ты его сюда приплел.

anonymous
()
Ответ на: комментарий от den73

Каждая следующая функция даст дополнительный отступ. Если их понадобится десяток, то получится коллбэк-каша, за которую JS и критиковали.

Как это выглядит с промисами (утянуто со стековерфлоу):

$.when(
    $.ajax("/first/call"),
    $.ajax("/second/call"),
    $.ajax("/third/call")
    )
    .done(function(first_call, second_call, third_call){
        //do something
    })
    .fail(function(){
        //handle errors
    });

Линейно и красиво.

Плюс ловятся исключения. Для замыканий нужен try/catch в каждой функции, здесь хватит одного блока в единственном месте.

anonymous
()
Ответ на: комментарий от anonymous

То что ты отрезал фразу про «одновременный запуск» от остальной части с которой она соединена через «и», исказив таким образом исходный смысл, ничего не меняет. Или ты думаешь что будь у тебя возможность создавать потоки они бы запускались одновременно?

ya-betmen ★★★★★
()
Ответ на: комментарий от den73

А я вот в tcl без всяких промисов строю цепочки сообщений. Просто назначаю «замыкание» на обработчик событий. Что я делаю не так?

Нормальные фьючеры, которые неявные, позволяют делать вот так


objectFoo.asyncSend("a") asyncSend("b") ...

то есть, ты шлешь сообщение не фьючеру, а возвращаемому объекту(фьючер после готовности сам им становиться)

А то что ты сказал, это никакая не цепочка, это просто один коллбек на событие.

А зачем избавляться от представления о стеке?

Фьючеры не совместимы с блокирующим кодом, они асинхронны по-определению.

anonymous
()
Ответ на: комментарий от ya-betmen

исходный смысл

исходный смысл неясен

они бы запускались одновременно

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

Еще раз. Одновременность/разновременность запуска чего либо к примисам не имеет ни малейшего отношения.

anonymous
()

а) избавиться от тредов там, где приходится их использовать

Одно другому не мешает. Промисы могут жить в каждом потоке. Конкурентно (асинхронно) != параллельно.

б) избавиться от цепочки сообщений и заменить её обычным стеком исполнения

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

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

В народе, замыкания. Зависит от ЯП и к промисам отношения не имеет. В случае JS, замыкания искоробки (хоть и со своими особенностями).

Все разжевано здесь: https://www.promisejs.org/

Как это сделать самому: https://www.promisejs.org/implementing/

gh0stwizard ★★★★★
()
Ответ на: комментарий от gh0stwizard

С this там свистопляски еще те

this никакого отношения к замыканиям не имеет. На лексический контекст замыкаются только лексические переменные.

anonymous
()
Ответ на: комментарий от gh0stwizard

Только на деле в JS this и замыкания очень плотно связаны. By design.

Никакой связи нет, абсолютно. Они взаимодействуют с разными контекстами, которые, практически, не пересекаются.

anonymous
()
Ответ на: комментарий от anonymous

исходный смысл неясен

Мне ясен.

Одновременность/разновременность запуска чего либо к примисам не имеет ни малейшего отношения.

В исходном посте не было ничего про одновременность запуска и промисы, это уже твоё творчество.

ya-betmen ★★★★★
()
Последнее исправление: ya-betmen (всего исправлений: 1)
Ответ на: комментарий от ya-betmen

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

anonymous
()
Ответ на: комментарий от anonymous

У тебя в кратковременную память длинные предложения целиком не помещаются что ли? Из того, что там слова «запуск» и «промис» написаны рядом ничего не следует.

ya-betmen ★★★★★
()
Ответ на: комментарий от ya-betmen

Короче, отвали, все ясно с тобой.

anonymous
()
Ответ на: комментарий от den73

В чём именно наступает облегчение?

Код визуально становится линейным вместо вложенного.

Еще учитывай, что промисы изобрели тогда, когда замыканий и генераторов в помине не было.

Vit ★★★★★
()
Ответ на: комментарий от Vit

Еще учитывай, что промисы изобрели тогда,

Промисы изобрели тогда, когда тебя еще в помине не было, во времена становления смоллтока где-то.

когда замыканий

Замыкания, чудило, в JS были практически с самого начала его существования. Если же говорить о замыканиях вообще то где то в 60 - х годах.

и генераторов

А теперь расскажи нам, как генераторы могут заменить промисы, посмеши народ.

anonymous
()
Ответ на: комментарий от Vit

Ты лучше расскажи, как с такими мозгами, и с таким уровнем знания программирования, и JS в частности (о чем несомненно свидетельствует вот этот, например перл — когда появились промисы замыканий не было [facepalm here], чуть ранее — строки в JS — полноценные объекты[doublefacepalm here]) можно писать хотя бы хелловорды. Ведь это же реальное днище. Реально же в это никто не поверит. Или поверит? Я теряюсь в догадках. BTW, может кто пояснит мне, что тут происходит вообще? Что за фарс?:) Как человек с такими понятиями может писать код?

anonymous
()
Ответ на: комментарий от anonymous

Да, еще и с пятью звездами кстати:)

anonymous
()
Ответ на: комментарий от newquestion

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

asaw ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.