Перейти к содержимому
HeroBrine1st

Lua Promise

Рекомендуемые сообщения

Для создания асихнронных библиотек по типу 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, она заблокирует промис. Учтите.

Изменено пользователем HeroBrine1st

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Только что, LeshaInc сказал:

async-await

thread.waitForAny({promise.thread})
local result = table.unpack(promise.result)

Я уже начал юзать эту либу (в который раз убеждаюсь, что ничего по приколу делать не могу) и дорабатываю ее, так что возможно эти 2 строки кода появятся в либке)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Кстати, из промисов в твоей либе только название, поскольку настоящие промисы можно собирать в цепочки: из then-коллбека можно вернуть новый промис. А еще есть удобные функции по типу Promise.all()

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
32 минуты назад, LeshaInc сказал:

можно собирать в цепочки

Чейнинг тут есть. Тут другая сторона медали - нельзя на один промис навешать 2 обработчика, только последовательно, друг за дружкой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
16 часов назад, LeshaInc сказал:

Кстати, из промисов в твоей либе только название, поскольку настоящие промисы можно собирать в цепочки: из then-коллбека можно вернуть новый промис. А еще есть удобные функции по типу Promise.all()

Сделал промисы наиболее похожими на настоящие. Нет только методов resolve и reject у самой либы (по-моему, особо не нужно). UPD: уже есть

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

Изменено пользователем HeroBrine1st

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

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

Гость
Ответить в тему...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...