Как вызвать асинхронную функцию в Promise .then () - PullRequest
0 голосов
/ 27 февраля 2019

Во-первых, я должен отметить, что я уже просмотрел много вопросов в stackoverflow, но многие не отвечают на мой вопрос.Не говоря уже о том, что многие даже не имеют ответа.

Как мне добиться следующего, убедившись, что functionB() выполняется после завершения functionA()?


ПримечаниеЯ не хочу преобразовывать свои асинхронные функции в new Promise(resolve=>{...})
, потому что мне придется также преобразовать someServiceThatMakesHTTPCall() и любые другие асинхронные функции в стеке вызовов, что является большим изменением.

  function functionThatCannotHaveAsyncKeyword() {
      functionA()
        .then(async function() {
            await functionB();
        })
        .then(function() {
            console.log('last');
        });
  }

  async function functionA() {
      console.log('first');
      await someServiceThatMakesHTTPCall();
  }

  async function functionB() {
      console.log('second');
      await someServiceThatMakesHTTPCall();
  }

Ответы [ 3 ]

0 голосов
/ 27 февраля 2019

если someServiceThatMakesHTTPCall является асинхронным, вы можете избежать всего этого, выполнив следующие действия:

function functionThatCannotHaveAsyncKeyword() {
    functionA()
        .then(function() {
            return functionB()
        })
        .then(function() {
            console.log('last');
        });
  }

  function functionA() {
      console.log('first');
      return someServiceThatMakesHTTPCall();
  }

  function functionB() {
      console.log('second');
      return someServiceThatMakesHTTPCall();
  }
0 голосов
/ 27 февраля 2019

Вы можете использовать обещание в первом методе как

function functionThatCannotHaveAsyncKeyword() {
    return new Promise(async(resolve, reject)=> {
          await functionA();
          await functionB();
          console.log('last');    
      });
  }

  async function functionA() {
      console.log('first');
      await someServiceThatMakesHTTPCall();
  }

  async function functionB() {
      console.log('second');
      await someServiceThatMakesHTTPCall();
  }
0 голосов
/ 27 февраля 2019

Ваш подход, использующий await в обратном вызове async then, будет работать, но он неоправданно сложен, если all , который вы хотите сделать, это вызвать функцию async и распространить ее результат черезцепь.Но если вы занимаетесь другими делами и хотите использовать преимущества синтаксиса async функций, это нормально.Я вернусь к этому через мгновение.

async функции возвращают обещания, поэтому вы просто возвращаете результат вызова своей функции:

function functionThatCannotHaveAsyncKeyword() {
  functionA()
    .then(function() {
        return functionB(someArgument);
    })
    .then(function() {
        console.log('last');
    }); // <=== Note: You need a `catch` here, or this function needs
        // to return the promise chain to its caller so its caller can
        // handle errors
}

Если вы хотите передать *Значение разрешения 1014 * в functionB, вы можете сделать это еще более напрямую:

functionA()
  .then(functionB)
  // ...

Когда вы возвращаете обещание из then обратного вызова, обещание, созданное вызовом thenподчинено обещанию, которое вы возвращаете.

Пример:

const wait = (duration, ...args) => new Promise(resolve => {
  setTimeout(resolve, duration, ...args);
});

async function functionA() {
  await wait(500);
  return 42;
}

async function functionB() {
  await wait(200);
  return "answer";
}

functionB()
.then(result => {
  console.log(result); // "answer"
  return functionA();
})
.then(result => {
  console.log(result); // 42
})
.catch(error => {
  // ...handle error...
});

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

const wait = (duration, ...args) => new Promise(resolve => {
  setTimeout(resolve, duration, ...args);
});

async function functionA() {
  await wait(500);
  return 42;
}

async function functionB() {
  await wait(200);
  return "answer";
}

functionB()
.then(async (result) => {
  console.log(result); // "answer"
  const v = await functionA();
  if (v < 60) {
    console.log("Waiting 400ms...");
    await wait(400);
    console.log("Done waiting");
  }
  console.log(v);      // 42
})
.catch(error => {
  // ...handle error...
});
...