Comments 25
void main()
{
auto content = getContent("http://httpbin.org/get");
auto json = parseJSON(content);
writeln(json);
}
Так круче:
void main()
{
writeln( "http://httpbin.org/get".getContent.parseJSON );
}
queryParams("name", "bob", "age", 101)
Как-то это криво, лучше бы использовали словари:
queryParams([ "name" : "bob" , "age" : "101" ])
Я так понимаю кроме POST и GET другие методы не поддерживаются?
getContent("http://httpbin.org/get", ["a":"hello", "b":"world"]);
Но есть ситуации, когда имя параметра повторяется:
getContent("http://httpbin.org/get", queryParams("name[]", "hello", "name[]", "world"));
И значения в словаре должны иметь один тип. Такое без предварительного преобразования в строку нельзя использовать:
getContent("http://httpbin.org/get", ["name":"bob", "age":42]);
Вместо повторяющихся параметров, можно сделать массивы в качестве значений:
"http://httpbin.org/get".getContent([ "name" : [ "hello", "world" ] , "age" : [ 42.to!string ] ]);
А что типы надо преобразовывать, так это нормально для языка со строгой типизацией.
Оба метода имеют сви плюсы и минусы, пользователь может выбрать то, что ему в данном случае подходит больше.
Тут преобразование вполне однозначное:
"http://httpbin.org/get".getContent([ "name[]" : [ "hello", "world" ] , "age" : [ 42.to!string ] ]);
http://httpbin.org/get?name[]=hello&name[]=world&age=42
Представляйте, никто вам не мешает:
"http://httpbin.org/get".getContent([
"name" : [ "[" ~ [ "hello", "world" ].joiner(",") ~ "]" ] ,
"age" : [ 42.to!string ]
]);
"http://httpbin.org/get".getContent([
"name" : [ "(" ~ [ "hello", "world" ].joiner(",") ~ ")" ] ,
"age" : [ 42.to!string ]
]);
Массивы в качестве значений решают не задачу передачи списков значений, а задачу передачи нескольких пар с одинаковыми ключами.
Не нужны там никакие async/await-ы используйте fibers&streams.
Если бы в D был механизм декораторов, то async/await можно было бы реализовать и самостоятельно, но, увы, UDA не дают возможности менять определение или тело функции.
А о каких strams идёт речь?
нужен еще event-loopУ нас есть живой пример того, как можно сделать это элегантно — asyncio из Python.
Или еще лучше — сделайте наконец-то AST Macros из DIP-50! Тогда async/await можно будет просто реализовать без участия комитета одобрения D — и не только его. stm, linq, шаблонизаторы в стиле jinja или jade, aop… Возможности безграничны, и все это без жертв производительности. Однозначно нужен DIP-50.
А в чём проблема завернуть создание и запуск волокна в функцию?
unittest
{
import core.time;
import std.range;
import jin.go;
__gshared static string[] log;
static void saying( string message )
{
foreach( _ ; 3.iota ) {
sleep( 100.msecs );
log ~= message;
}
}
go!saying( "hello" );
sleep( 50.msecs );
saying( "world" );
log.assertEq([ "hello" , "world" , "hello" , "world" , "hello" , "world" ]);
}
Что такое "semi-coroutine"? Почему вы считаете stackless сопрограммы, требующие костылей в виде async/await, единственно верными?
Тогда рекомендую почитать эту статью: https://habrahabr.ru/post/280378/
go! запускает функцию в отдельном волокне.
Очевидно, эти процедуры никогда не проснутся и так и останутся висеть заблокированными. Если сработает таймаут, то он приведёт к пробуждению процедуры с возникновением в ней исключения.
Если в отдельном волокне, то это хорошо, но не очень экономно. Мне больше нравится подход Fiber + неблокированный io, который, по идее, берёт лучшее от двух миров — «синхронный» код + скорость неблокированного io.
Ну так vibe.d как раз реализует неблокирующий io.
Вот уж не знаю, что там такого не удобного.
shared static this()
{
runWorkerTask({
logInfo( "Request IP..." );
logInfo( "IP: %s" , "http://httpbin.org/ip".requestHTTP.readJson["origin"] );
});
runWorkerTask({
logInfo( "Request UA..." );
logInfo( "UA: %s" , "http://httpbin.org/user-agent".requestHTTP.readJson["user-agent"] );
});
}
Request IP...
Request UA...
IP: "5.144.98.1"
UA: "vibe.d/0.7.28 (HTTPClient, +http://vibed.org/)"
dlang-requests — типа python-requests, только для D