Исходя из nodejs, где я мог связать асинхронные события, используя обещания, а затем оператор Я пытаюсь изучить, как все делается в идиоматическом F#.
Вызовы, которые я пытаюсь связать, представляют собой остаточные вызовы HTTP для некоторого объекта от создания до обновления и загрузки изображений для публикации.
Композиция функций говорит, что выходные данные одной функции должны совпадать с входными данными второй, и что общий ввод и вывод в моем случае будут string
, то есть сериализованная строка JSON в качестве ввода и вывода всех этих функций.
Я узнал, что вы можете составлять функции, используя оператор >>
. В идеале функции не должны выдавать ошибок, но с вводом-выводом случаются вещи, например, в этом случае, что если идентификатор объекта, который я пытаюсь создать, существует и т. д.
Неизвестно, и вопрос заключается в том, что произойдет, если во время цепочки последовательности произойдет ошибка, как вызывающий абонент узнает, что пошло не так, вместе с описательным сообщением? Операция может завершиться ошибкой в середине, ближе к концу или прямо в начале последовательности цепочки.
Что я ожидаю от этих функций при ошибке, чтобы остановить выполнение цепочки и вернуть сообщение об ошибке вызывающей стороне. Сообщение об ошибке также представляет собой JSON string
, поэтому между входными и выходными данными функции нет несовместимости.
Я просмотрел Choice тоже, но не уверен, что это то направление, в котором я должен двигаться.
Код не обязательно является полным, и все, что я ищу, - это направление для дальнейших исследований, чтобы получить ответы и, возможно, улучшить этот вопрос. Вот код для начала.
let create schema =
// POST request
"""{"id": 1, "title": "title 1"}""" // result output
let update schema =
// PUT request, update title
"""{"id": 1, "title": "title 2"}""" // output
let upload schema =
// PUT request, upload image and add thumbnail to json
"""{"id": 1, "title": "title 2", "thumbnail": "image.jpg"}"""
let publish schema =
// PUT request, publish the entity, add url for the entity
if response.StatusCode <> HttpStatusCode.OK then
"""{"code": "100", "message": "file size above limit"}"""
else
"""{"id": 1, "title": "title 2", "thumbnail": "image.jpg", "url": "http://example.com/1"}"""
let chain = create >> update >> upload >> publish
Редактировать — Попытка
Попытка параметризовать миниатюру изображения в части загрузки
let create (schema: string) : Result<string,string> =
Ok """{"id": 1, "title": "title 1"}""" // result output
let update (schema: string) : Result<string,string> =
Ok """{"id": 1, "title": "title 2"}""" // output
let upload2 (img: string) (schema: string) : Result<string,string> =
printf "upload image %s\n" img
let statusCode = HttpStatusCode.OK
match statusCode with
| HttpStatusCode.OK -> Ok """{"id": 1, "title": "title 2", "thumbnail": "image.jpg"}"""
| x -> Error (sprintf "%A happened" x)
let publish (schema: string) =
let statusCode = HttpStatusCode.InternalServerError
match statusCode with
| HttpStatusCode.OK -> Ok """{"id": 1, "title": "title 2", "thumbnail": "image.jpg", "url": "http://example.com/1"}"""
| _ -> Error """{"code": "100", "message": "couldn't publish, file size above limit"}"""
let chain = create >> Result.bind update >> Result.bind (upload2 "image.jpg") >> Result.bind publish