Non-blocking DNS lookup - specifically ESP8266 Arduino

I am building an ESP8266 based NTP clock. It shows hours, minutes, and seconds on LED's, with seconds updating (ideally) every second within a fraction of a second of actual time.

It uses pool.ntp.org with a reasonable poll interval (15 minutes), and does a DNS lookup on that periodically (a few times a day) because pool servers can come and go over time, and I want the clock to just hang on the wall forever without human intervention.

I know how to send and receive UDP packets non-blocking for the polling. So if I send a poll to a NTP server and it doesn't respond, I just mark it as a no response after one second and try later. So this is great: I understand basic non-blocking UDP packets.

It's important that the code update the human-readable seconds digit on the LED display of the clock every second because, well, it's a clock. And I have no problem meeting this requirement with the UDP packet polls because they are done non-blocking.

BUT then there's the issue of DNS lookups which I don't know how to do non-blocking.

If I do a DNS lookup on pool.ntp.org before DNS Time-To-Live has expired, it takes less than a millisecond most of the time so must be using a cached value. After Time-To-Live has expired it usually takes 20-30 milliseconds to do a DNS lookup which is entirely typical for DNS on my WiFi.

BUT SOMETIMES the DNS lookup takes several seconds and succeeds, or as much as 8 seconds and fails. I use the code fragment below to do the DNS lookup, and while it usually takes less than 30 milliseconds, it occasionally takes up to 8 seconds, and while blocking my seconds digit doesn't update. Is there some easy way to do something similar to this, but have the DNS lookup timeout in less than a second, or to do the DNS lookup in a non-blocking way?

IPAddress timeServerIP; // time.nist.gov NTP server address
const char* ntpServerName = "pool.ntp.org";
WiFi.hostByName(ntpServerName, timeServerIP);

I recently found out that you really don't have to go through all of that to update from NTP. All it takes is a few lines of code to make the connection, get the time information, convert it to your local time (including DST adjustments) etc.

Here are the key points, I can get you more information if you need it.

You need to include the time.h (lower case 't') and coredecls.h libraries. I don't remember downloading them so they must be provided with the IDE.

You implement the NTP update, including a automatic hourly update (not adjustable as far as I can tell) with: configTime(0, 0, "0.pool.ntp.org");

You implement the conversion from UNIX time to local time with:

setenv("TZ", "EST+5EDT,M3.2.0/2:00:00,M11.1.0/2:00:00", 1);

This should work for you in the Eastern time zone of the US, others will have to check out information about POSIX and TZ.

You also can register a callback which is activated when the NTP update is successful:

settimeofday_cb(time_is_set);

Don