等待功能按顺序完成Javascript

时间:2019-03-07 00:21:29

标签: javascript asynchronous promise

我有三个函数,分别根据setTime打印20,30,10Timeout我应该如何使它们使用promise打印10,20,30订单
如何编写这些回调以打印正确的顺序。

P.S。 :这不是重复的问题。谢谢 !

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

2 个答案:

答案 0 :(得分:2)

我不确定100%是否了解您的问题。但是,这里是基于我的理解。您没有对回调做任何事情,所以我没有通过它们。 在您的代码函数B中没有延迟。

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

答案 1 :(得分:1)

如果您要遵守Promises,则可以创建一个执行setTimeout但返回Promise的助手函数。这将保留控制台日志的顺序:

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

或者,如果您想要一个干净的解决方案并且不介意添加第三方模块,则可以使用async-af,这是我维护的可链接异步JavaScript方法的库:

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/async-af@7.0.11/index.js"></script>