Using setTimeout on promise chain

Here i am trying to wrap my head around promises.Here on first request i fetch a set of links.and on next request i fetch the content of first link.But i want to make a delay before returning next promise object.So i use setTimeout on it. But it gives me the following JSON error (without setTimeout() it works just fine)

SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

i would like to know why it fails?

let globalObj={}; function getLinks(url){ return new Promise(function(resolve,reject){ let http = new XMLHttpRequest(); http.onreadystatechange = function(){ if(http.readyState == 4){ if(http.status == 200){ resolve(http.response); }else{ reject(new Error()); } } } http.open("GET",url,true); http.send(); }); } getLinks('links.txt').then(function(links){ let all_links = (JSON.parse(links)); globalObj=all_links; return getLinks(globalObj["one"]+".txt"); }).then(function(topic){ writeToBody(topic); setTimeout(function(){ return getLinks(globalObj["two"]+".txt"); // without setTimeout it works fine },1000); }); 
4

7 Answers

To keep the promise chain going, you can't use setTimeout() the way you did because you aren't returning a promise from the .then() handler - you're returning it from the setTimeout() callback which does you no good.

Instead, you can make a simple little delay function like this:

function delay(t, v) { return new Promise(function(resolve) { setTimeout(resolve.bind(null, v), t) }); } 

And, then use it like this:

getLinks('links.txt').then(function(links){ let all_links = (JSON.parse(links)); globalObj=all_links; return getLinks(globalObj["one"]+".txt"); }).then(function(topic){ writeToBody(topic); // return a promise here that will be chained to prior promise return delay(1000).then(function() { return getLinks(globalObj["two"]+".txt"); }); }); 

Here you're returning a promise from the .then() handler and thus it is chained appropriately.


You can also add a delay method to the Promise object and then directly use a .delay(x) method on your promises like this:

function delay(t, v) { return new Promise(function(resolve) { setTimeout(resolve.bind(null, v), t) }); } Promise.prototype.delay = function(t) { return this.then(function(v) { return delay(t, v); }); } Promise.resolve("hello").delay(500).then(function(v) { console.log(v); });

Or, use the Bluebird promise library which already has the .delay() method built-in.

12
.then(() => new Promise((resolve) => setTimeout(resolve, 15000))) 

UPDATE:

when I need sleep in async function I throw in

await new Promise(resolve => setTimeout(resolve, 1000)) 
0

The shorter ES6 version of the answer:

const delay = t => new Promise(resolve => setTimeout(resolve, t)); 

And then you can do:

delay(3000).then(() => console.log('Hello')); 
2

If you are inside a .then() block and you want to execute a settimeout()

 .then(() => { console.log('wait for 10 seconds . . . . '); return new Promise(function(resolve, reject) { setTimeout(() => { console.log('10 seconds Timer expired!!!'); resolve(); }, 10000) }); }) .then(() => { console.log('promise resolved!!!'); }) 

output will as shown below

wait for 10 seconds . . . . 10 seconds Timer expired!!! promise resolved!!! 

Happy Coding!

0

Since node v15, you can use timers promise API

example from the doc:

import { setTimeout } from 'timers/promises' const res = await setTimeout(100, 'result') console.log(res) // Prints 'result' 

In node.js you can also do the following:

const { promisify } = require('util') const delay = promisify(setTimeout) delay(1000).then(() => console.log('hello')) 
2
const myStuff = new Promise(function (resolve) { console.log("before timeout"); setTimeout( function (x) { console.log("inside the timeout"); resolve(x); }, 3000, "after timeout" ); }).then((response) => console.log(response)); 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like