1

I have three functions prints 20,30,10 as per setTimeout how should i make them print 10,20,30 order using promise
How to write these callbacks to print right order.

P.S. : This is not a duplicate question. Thanks !

var A = function(callback) {
    setTimeout(function() {
        console.log(10)
        callback();
    }, 2000);
};

var B = function(callback) {
    console.log(20);
    callback();
};

var C = function(callback) {
    setTimeout(function() {
        console.log(30)
        callback();
    }, 200);
};

function runTask() {
  var wait = ms => new Promise ((resolve,reject) => setTimeout(resolve, ms))
  var FuncA = wait();
  FuncA.then(() => A(function () {}))
   . then(() => B(function () {}))
    .then(() => C(function () {}));
}

runTask();

0

2 Answers 2

2

I'm not 100% sure I understood your question. But, here it is based on what I understood. You weren't doing anything with the callback so I didn't pass them. In your code function B didn't have a delay.

function delayAsync(ms) {
    return new Promise(p_resolve => setTimeout(p_resolve, ms));
}

async function A(callback) {
    await delayAsync(2000);
    console.log(10);
    if (callback instanceof Function) {
        callback();
    }
}

async function B(callback) {
    console.log(20);
    if (callback instanceof Function) {
        callback();
    }
}

async function C(callback) {
    await delayAsync(200);
    console.log(30);
    if (callback instanceof Function) {
        callback();
    }
}

function runTask() {

    return new Promise(async (resolve, reject) => {
        await A();
        await B();
        await C();
        resolve();
    });
}

runTask().then(() => console.log('done'));

Sign up to request clarification or add additional context in comments.

Comments

1

If you want to stick with Promises, you could create a helper function that performs a setTimeout but returns a Promise. This will preserve the order of console logs:

const setTimeoutAsync = (fn, ms) => new Promise(resolve => setTimeout(() => resolve(fn()), ms));

var A = function(callback) {
    return setTimeoutAsync(() => {
        console.log(10)
        callback();
    }, 2000);
};

var B = function(callback) {
    console.log(20)
    callback();
};

var C = function(callback) {
    return setTimeoutAsync(() => {
        console.log(30)
        callback();
    }, 200);
};

function runTask() { // refactored since A now returns a Promise
    return A(() => {})
        .then(() => B(() => {}))
        .then(() => C(() => {}));
}

runTask();

Alternatively, if you'd like a clean solution and don't mind adding a third party module, you could use async-af, a library for chainable asynchronous JavaScript methods that I maintain:

const setTimeoutAsync = (fn, ms) => new Promise(resolve => setTimeout(() => resolve(fn()), ms));

var A = function(callback) {
    return setTimeoutAsync(() => {
        console.log(10)
        callback();
    }, 2000);
};

var B = function(callback) {
    console.log(20)
    callback();
};

var C = function(callback) {
    return setTimeoutAsync(() => {
        console.log(30)
        callback();
    }, 200);
};

// to run in parallel you would omit `series`, but
// since you want to run the tasks in order include it:
function runTask(...tasks) {
      return AsyncAF(tasks).series.forEach(task => task(() => {}));
}

runTask(A, B, C);
<script src="https://unpkg.com/[email protected]/index.js"></script>

1 Comment

Thanks Scott for providing different approaches ! I am curious, how will you do it without changing A, B, C functions. ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.