[javascript] 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);
});

This question is related to javascript json promise

The answer is


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:

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

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


.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))

In node.js you can also do the following:

const { promisify } = require('util')
const delay = promisify(setTimeout)

delay(1000).then(() => console.log('hello'))

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'));

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!


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to json

Use NSInteger as array index Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>) HTTP POST with Json on Body - Flutter/Dart Importing json file in TypeScript json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 190) Angular 5 Service to read local .json file How to import JSON File into a TypeScript file? Use Async/Await with Axios in React.js Uncaught SyntaxError: Unexpected token u in JSON at position 0 how to remove json object key and value.?

Examples related to promise

Axios handling errors typescript: error TS2693: 'Promise' only refers to a type, but is being used as a value here Syntax for async arrow function Angular 2: How to call a function after get a response from subscribe http.post How to use fetch in typescript Returning Promises from Vuex actions Use async await with Array.map Getting a UnhandledPromiseRejectionWarning when testing using mocha/chai using setTimeout on promise chain Why is my asynchronous function returning Promise { <pending> } instead of a value?