Как правильно определить обратный вызов, который будет запускаться после вызывающей его функции? - PullRequest
3 голосов
/ 23 мая 2019

Например, я хотел бы определить обратный вызов, который показывает сообщение о завершении задачи только с использованием обратных вызовов . Пожалуйста, не говорите об Обещаниях, я знаю, что это может быть применено здесь.

1. Моя первая попытка:

function doHomeWork (subject, callback) {
    setTimeout(() => {
        console.log(`Started my ${subject} homework`);
    }, 500);
    callback(subject);
}

function finishedHomework (subject) {
    console.log(`Finished my ${subject} homework`);
}

doHomeWork('math', finishedHomework);

Это печатает Finished.. до Started.., потому что callback(subject) не ждет конца setTimeout.

Если я позвоню callback(subject) в setTimeout, он напечатает оба сообщения одновременно, а не то, что я хочу.

Этот ответ помещает setTimeout в вызов обратного вызова, но в моем гипотетическом случае время потребляет doHomeWork, а не обратный вызов finishedHomeWork, так что это не допустимо для этого примера.

2. Моя вторая попытка:

function homeWork (subject, callback) {
    doHomeWork(subject);
    callback(subject);
}

function doHomeWork (subject) {
    setTimeout(() => {
        console.log(`Started my ${subject} homework`);
    }, 500);
}

function finishedHomework (subject) {
    console.log(`Finished my ${subject} homework`);
}

homeWork('math', finishedHomework);

Это также печатает Finished.. до Started.., потому что callback(subject) не ждет doHomeWork(subject).

Итак, объяснение обратного вызова говорит, что это функция, которая будет запускаться после функции, вызывающей ее, не так ли? Но, как показали мои примеры, я не нашел способа определить его для запуска после финиша doHomeWork.

Чего не хватает?

Ответы [ 3 ]

2 голосов
/ 23 мая 2019

Привет, проблема в том, что когда это функция

() => {console.log(`Started my ${subject} homework`);}

запускается только когда заканчивается setTimeout, поэтому лучшее решение, которое я вижу, это

function doHomeWork (subject, callback) {
    console.log(`Started my ${subject} homework`);
    setTimeout(() => {
        callback(subject);
    }, 500);
}
2 голосов
/ 23 мая 2019

Во-первых, именно поэтому вам нужны обещания.

Javascript не волнует, что ваш второй параметр является обратным вызовом. Он запустит функцию обратного вызова, как только сможет, потому что не ожидает завершения предыдущего вызова, что вы продемонстрировали в двух своих примерах.

Чтобы сделать это только с обратными вызовами, поместите ваш обратный вызов внутри функции setTimeout.

function doHomeWork (subject, callback) {
    setTimeout(() => {
        console.log(`Started my ${subject} homework`);
        callback(subject); // <---------   CHANGE MADE HERE
    }, 500);
    //callback(subject)  // Remove this line, and move it up ^^^
}

function finishedHomework (subject) {
    console.log(`Finished my ${subject} homework`);
}

doHomeWork('math', finishedHomework);

Однако , вы должны просто использовать Обещания. Они на самом деле легко и гораздо более читабельны. Та же функция может быть записана как:

function doHomeWork (subject) {
  return new Promise( (resolve,reject) => {   //Turns a regular funciton into a promise
    setTimeout(() => {
        console.log(`Started my ${subject} homework`);
        resolve(subject);
    }, 500);
  }); 
}

function finishedHomework (subject) {
    console.log(`Finished my ${subject} homework`);
}

doHomeWork('math').then( (subject) => { //since doHomeWork returns a promise we can use .then() on it
    finishedHomework(subject);
});
0 голосов
/ 23 мая 2019

Может быть, попробовать обернуть ваш обратный вызов в анонимную функцию?(Не проверено, но обычно это мое первое предположение, когда у меня возникает та же проблема, с которой вы сталкиваетесь.)

homeWork('math', function(){finishedHomework()});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...