HeroBrine1st 88 Опубликовано: 2 февраля, 2019 (изменено) Для создания асихнронных библиотек по типу vk-fast-longpoll у nodejs. pastebin get 4Lh9ALEY /lib/Promise.lua Методы библиотеки: all(iterable: table) - создает промис, который ждет завершения всех переданных промисов (в виде таблицы) и в resolve шлет таблицу со всеми их значениями. Если хоть один завершится с ошибкой, вызовет reject с этой ошибкой race(iterable: table) - создает промис, который ждет первого завершения любого промиса, и проксифицирует его результат на себя (т.е. ошибку или результат перекидывает через себя, не обрабатывая) resolve(value:any) - создает промис, который успешно завершился с параметром value reject(value:any) - создает промис, который завершился с ошибкой value Магия ООП начинается с магии метатаблиц - вызывайте библиотеку как функцию. Просто Promise(...). Аргумент один - функция, принимающая 2 аргумента - resolve и reject. Если промис завершает работу успешно, он вызывает функцию resolve с одним (!) аргументом, а та передает его обработчикам. Если с ошибкой - вызывает reject, либо он вызывается автоматически при синхронной ошибке (attempt to call a nil value, error(...) и все подобное). Возвращает класс. У него 3 метода: next(onResolve:function,onReject:function): self: object (__name=Promise) - аналог then в NodeJS. catch(onReject): self: object (__name=Promise) - думаю понятно. await - ждет завершения промиса и возвращает его результат. Поддерживается чейнинг, но паралельные обработчики не добавить, и я не знаю, как это исправить :C Если во время чейнинга из обработчика вернуть промис, библиотека будет ждать его завершения и передаст результат в следующий обработчик. Если на уже выполненный промис навесить обработчик, он выполнится синхронно. На выполняющийся - асинхронно после завершения. Обьяснил возможно непонятно, обьяснение на learn.javascript.ru. Примеры кода: local Promise = require("Promise") local p = Promise(function(resolve,reject) print(123) os.sleep(5) print(234) resolve(5) end) --123 p:next(function(result) print(result) return 8 end) os.sleep(5) --234 --5 print(p.result) --8 a=Promise(function(a,b) os.sleep(5) a(1) end) b=Promise(function(a,b) os.sleep(1) a(2) end) c = Promise.all({a,b}) c:onResolve(function(values) print(serialization.serialize(values)) end) d = Promise.race({a,b}) d:onResolve(function(values) print(values) end) os.sleep(10) --2 --{2,1} Чистый исходный код на MoonScript Если туда не засовывать os.sleep, то промис заблокирует остальные потоки, как и если в основную программу не вставить os.sleep, она заблокирует промис. Учтите. Изменено 3 февраля, 2019 пользователем HeroBrine1st Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
LeshaInc 625 Опубликовано: 2 февраля, 2019 А теперь сделай async-await на короутинах Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
HeroBrine1st Автор темы 88 Опубликовано: 2 февраля, 2019 Только что, LeshaInc сказал: async-await thread.waitForAny({promise.thread}) local result = table.unpack(promise.result) Я уже начал юзать эту либу (в который раз убеждаюсь, что ничего по приколу делать не могу) и дорабатываю ее, так что возможно эти 2 строки кода появятся в либке) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
LeshaInc 625 Опубликовано: 2 февраля, 2019 Кстати, из промисов в твоей либе только название, поскольку настоящие промисы можно собирать в цепочки: из then-коллбека можно вернуть новый промис. А еще есть удобные функции по типу Promise.all() Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
HeroBrine1st Автор темы 88 Опубликовано: 2 февраля, 2019 32 минуты назад, LeshaInc сказал: можно собирать в цепочки Чейнинг тут есть. Тут другая сторона медали - нельзя на один промис навешать 2 обработчика, только последовательно, друг за дружкой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
HeroBrine1st Автор темы 88 Опубликовано: 2 февраля, 2019 (изменено) 16 часов назад, LeshaInc сказал: Кстати, из промисов в твоей либе только название, поскольку настоящие промисы можно собирать в цепочки: из then-коллбека можно вернуть новый промис. А еще есть удобные функции по типу Promise.all() Сделал промисы наиболее похожими на настоящие. Нет только методов resolve и reject у самой либы (по-моему, особо не нужно). UPD: уже есть + даже если на уже выполненный промис добавить обработчик, он выполнится, если соблюдены его условия. Надеюсь, без дубликатов других промисов и нареканий. Изменено 3 февраля, 2019 пользователем HeroBrine1st Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах