Skip to content

Instantly share code, notes, and snippets.

@joepie91
Last active July 29, 2022 20:02
Show Gist options
  • Star 54 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save joepie91/2664c85a744e6bd0629c to your computer and use it in GitHub Desktop.
Save joepie91/2664c85a744e6bd0629c to your computer and use it in GitHub Desktop.
ES6 Promise.delay
module.exports = function(duration) {
return function(){
return new Promise(function(resolve, reject){
setTimeout(function(){
resolve();
}, duration)
});
};
};
// Usage:
var delayPromise = require("./delay-promise");
doThing()
.then(...)
.then(delayPromise(5000))
.then(...)
@joshkel
Copy link

joshkel commented May 26, 2016

A slight revision to support passing arguments through:

function delayPromise(duration) {
  return function(...args){
    return new Promise(function(resolve, reject){
      setTimeout(function(){
        resolve(...args);
      }, duration)
    });
  };
}

@robinpokorny
Copy link

Well written! I was looking for such copy 'n paste code.

BTW I like to call it sleep, as discussed here: https://esdiscuss.org/topic/promise-returning-delay-function

@Thaina
Copy link

Thaina commented Sep 27, 2016

I think it shorter if just

new Promise((resolve) => setTimeout(resolve,100));

@mceachen
Copy link

Or TypeScript, with generics:

function delay<T>(millis: number, value?: T): Promise<T> {
  return new Promise((resolve) => setTimeout(resolve(value), 100))
}

@KostyaEsmukov
Copy link

@mceachen There's a small typo in your code: you must have forgotten to replace the 100 with the millis.

@shaoshing
Copy link

let delay = (time) => (result) => new Promise(resolve => setTimeout(() => resolve(result), time));

Promise.resolve("Data")
    .then(delay(1000))
    .then(result => console.info(result));

@cwg999
Copy link

cwg999 commented Aug 8, 2017

Or ECMAScript 2017,

(async () =>{
  const delay = time => new Promise(res=>setTimeout(()=>res(),time));
  await delay(2000);
  console.log('Hotdog');
})();

@jesseschalken
Copy link

@mceachen In addition to what @KostyaEsmukov said, your TS version calls resolve immediately. resolve(value) should be () => { resolve(value) }.

@moneydance
Copy link

moneydance commented Apr 4, 2018

Heres a function that makes the promise take at least time milliseconds to resolve. Good if you have a really fast request but want to show a loading state for it.

const delay = (time, promise) =>
  Promise.all([
    promise,
    new Promise(resolve => setTimeout(resolve, time))
  ]).then(([response]) => response);

@PabloCorso
Copy link

PabloCorso commented Apr 14, 2018

A slight variation could be:

const delay = ms => new Promise(_ => setTimeout(_, ms));

// usage:
function sayWoof() {
  delay(1000).then(() => console.log("Woof"));
}

// ECMAScript 2017:
async function sayWoof() {
  await delay();
  console.log("Woof");
}

@toonvanvr
Copy link

toonvanvr commented Aug 23, 2018

There's no need for a timeout. It seems that the app.disableHardwareAcceleration() behaves like an unawaited function call. In my case, setTimeout with 0 delay works.

I believe this means that a disableHardwareAcceleration() is a queued task with no internal awaitable tasks, thus kind of atomic.
EDIT: has atomic behavior OR finishes so quickly (as parallel native code) that waiting for app.on('ready') always takes a longer time. This is hypothetical as I haven't checked the code. It's possible that the execution time varies depending on your hardware, resulting in the 0-delay to be an insufficient measure.

$ electron .
app.disableHardwareAcceleration()
app.on('ready', () => setTimeout(createWindow))

@berstend
Copy link

As I find myself ending up on this very page approx. once a week (copy pasting @PabloCorso version), here's a Node.js specific alternative for my future self 😄

const delay = require("util").promisify(setTimeout)

@justsml
Copy link

justsml commented Feb 11, 2019

Hi @berstend - I don't think util.promisify does what you hoped.

It expects a function whose callback argument is last. setTimeout's callback method is first, and timeout in milliseconds is 2nd. (The rarely used context arg is 3rd.)

This necessitates a wrapper function, I use something similar to https://gist.github.com/joepie91/2664c85a744e6bd0629c#gistcomment-2555399 :

const delay = ms => new Promise(yea => setTimeout(yea, ms));

delay(1000)
  .then(() => console.log('waited 1000 secs'))

@jgerstle
Copy link

@justml I'm fairly certain you are wrong as it's in nodejs's documentation

@nbouvrette
Copy link

@justml @jgerstle

I confirm that the following code works perfectly with Node.js:

const wait = require('util').promisify(setTimeout);

(async () => {
    console.log('Wait...');
    await wait(1000);
    console.log('...a second.');
})();

@berstend
Copy link

berstend commented Nov 13, 2019

Hello future self, here's the TypeScript version for your copy/pasting pleasure:

const delay = (ms: number) => new Promise(_ => setTimeout(_, ms))

and my favorite JS version:

const delay = ms => new Promise(_ => setTimeout(_, ms))

@tolotrasmile
Copy link

You forget to clear the setTimeout

const delay = async <T>(timeout: number, value?: T) => {
    return new Promise((resolve) => {
        const timeoutId = setTimeout(() => {
            resolve(value);
            clearTimeout(timeoutId);
        }, timeout);
    });
};

@joepie91
Copy link
Author

joepie91 commented May 5, 2020

@tolotrasmile That shouldn't be necessary, since this is a setTimeout, not a setInterval. A setTimeout only ever fires once, so once you're in the callback, there is nothing to clearTimeout anymore.

clearTimeout is basically just for cancelling a setTimeout that has not yet occurred.

@sannajammeh
Copy link

For nodeJS only

import { setTimeout } from "timers/promises";

await setTimeout(3000, value);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment