I don't follow at all. Setting the delay before the real result has arrived doesn't mean anything. After 20 seconds there is nothing you can do if the result is not available, so setting a 20 second delay without setting a value is completely pointless. What you should do is call delay(5, value) when the value is available. Then the timeout can be removed becase 15 > 5. If the value arrives after 35 seconds, calling delay(-15, value) will throw because the promise has already been fulfilled (broken?) by the timeout. (You could provide a try_delay which does not throw as well.)