обещания в путанице JavaScript - PullRequest
0 голосов
/ 10 июня 2018

Почему мой код иногда печатает "C" до "A"?

function printstring(string) {
  return new Promise((resolve, reject) => {
    setTimeout(function() {
      document.write(string);
      resolve();
    }, Math.floor(Math.random() * 100) + 1);
  })
}

function printall() {
  printstring("A")
    .then(printstring("C"))
}

printall();

Ответы [ 3 ]

0 голосов
/ 10 июня 2018
 printstring("A")
   .then(printstring("C"))

равно:

const promise1 = printstring("A");
const promise2 = printstring("C");

 promise1.then(promise2)

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

printstring("A").then(function() {
  printstring("C");
});
0 голосов
/ 10 июня 2018

Я полагаю, что это не имеет ничего общего с обещаниями.

Всякий раз, когда вы пишете такой код -

function mainFn(callback) {
    // do async stuff
    // call callback when done
    callback();
}

// callback handler
function callbackFn() {
    console.log('callback fn');
}

Вы должны убедиться, что передаете ссылку функции обратного вызова напараметр обратного вызова mainFn(), например, -

// Passess reference to callback function inside mainFn
mainFn(callbackFn);

Однако делать что-то вроде -

// Executes the callback function and passes it's result into mainFn
mainFn(callbackFn()); 

совершенно неправильно.Это похоже на то, что вы делаете с .then(printstring("C")).Сначала он выполнит printstring("C").

Итак, чтобы справиться с этим, оберните его в анонимную функцию, например, так -

 function printall() {
  printstring("A")
    .then(function() { printstring("C"); })
 }
0 голосов
/ 10 июня 2018

then ожидает обратного вызова.Этот обратный вызов вызывается, и в качестве параметра передается разрешенное значение обещания.

В своем коде вы указали printstring('C') в качестве обратного вызова.Таким образом, результат printstring('C'), который снова является обещанием, будет выполнен с ответом.Поскольку вы использовали случайный тайм-аут для выполнения, порядок печати на документе будет зависеть от него.Если тайм-аут печати C истекает до тайм-аута печати A, C обязательно будет напечатан первым.

Чтобы исправить это, используйте анонимную функцию в качестве обратного вызова then, т.е. преобразуйте это:

.then(printstring("C"))

к этому:

.then(() => printstring("C"))

См. Следующую рабочую демонстрацию:

function printstring(string) {
  return new Promise((resolve, reject) => {
    setTimeout(function() {
      document.write(string);
      resolve();
    }, Math.floor(Math.random() * 100) + 1);
  })
}

function printall() {
  printstring("A")
    .then(() => printstring("C"))
}

printall();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...