Дождитесь завершения функции в последовательности Javascript - PullRequest
1 голос
/ 07 марта 2019

У меня есть три функции, которые печатают 20,30,10 в соответствии с setTimeout, как мне заставить их напечатать 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 ]

2 голосов
/ 07 марта 2019

Я не уверен на 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 голос
/ 07 марта 2019

Если вы хотите придерживаться 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...