Должен ли я использовать async / await или обещания? - PullRequest
0 голосов
/ 30 октября 2018

Я ищу ответ о том, что использовать в моем приложении nodeJS.

У меня есть код, который обрабатывает мой общий доступ в дБ к mssql. Этот код написан с использованием async функций, а затем я использовал обещание вызвать эту функцию, и все работает нормально.

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

Итак, мой вопрос: Есть ли недостаток в использовании смеси async / await и обещаний или это действительно не имеет значения?

Async / await облегчает написание более читабельного кода, так как мне приходится читать и записывать в несколько БД, прежде чем что-то вернуть, и мне нужны результаты некоторых из них.

Итак, вопрос в том, какой подход лучше? Асинхронизация / ожидание на уровне дБ, который установлен и не может быть изменен Логический уровень async / await, который позволил бы мне асинхронизировать / и ожидать при вызове функции или, если я выполняю обещание логики, я застреваю с обещанием вызова функции.

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

Ответы [ 4 ]

0 голосов
/ 30 октября 2018

async/await и обещания тесно связаны между собой. async функции возвращают обещания, а ожидание является синтаксическим сахаром для ожидания разрешения обещания.

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

Выбор одного или другого в основном зависит от доступности (поддерживает ли ваш node.js / браузер async?) И от ваших эстетических предпочтений, но от хорошего эмпирического правила (основанного на моих собственных предпочтениях во время написание) может быть:

Если вам нужно запустить асинхронный код последовательно: рассмотрите возможность использования async/await:

return asyncFunction()
.then(result => f1(result))
.then(result2 => f2(result2));

против

const result = await asyncFunction();
const result2 = await f1(result);
return await f2(result2);

Если вам нужны вложенные обещания: используйте async/await:

return asyncFunction()
.then(result => {
  return f1(result)
  .then(result2 => f2(result, result2);
})

против

const result = await asyncFunction();
const result2 = await f1(result);
return await f2(result, result2);

Если вам нужно запустить его параллельно: используйте обещания.

return Promise.all(arrayOfIDs.map(id => asyncFn(id)))

Предполагалось, что вы можете использовать await в выражении для ожидания нескольких задач, например:
* обратите внимание, это все еще ожидает в последовательности слева направо, что нормально, если вы не ожидаете ошибок. В противном случае поведение отличается из-за сбой быстрого поведения из Promise.all()

const [r1, r2, r3] = [await task1, await task2, await task3];

(async function() {
  function t1(t) {
    console.time(`task ${t}`);
    console.log(`start task ${t}`);
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.timeEnd(`task ${t}`);
        resolve();
      }, t);
    })
  }

  console.log('Create Promises');
  const task1 = t1(100);
  const task2 = t1(200);
  const task3 = t1(10);

  console.log('Await for each task');
  const [r1, r2, r3] = [await task1, await task2, await task3];

  console.log('Done');
}())

Но, как и в случае Promise.all, параллельные обещания должны быть правильно обработаны в случае ошибки. Вы можете прочитать больше об этом здесь .

Также будьте осторожны, чтобы не путать это с этим, так как на практике это будет запускать задачи последовательно. Задачи должны быть уже запущены .

let [r1, r2] = [await t1(100), await t2(200)];

function t1(t) {
  console.time(`task ${t}`);
  console.log(`start task ${t}`);
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.timeEnd(`task ${t}`);
      resolve();
    }, t);
  })
}
console.log('Promise');
Promise.all([t1(100), t1(200), t1(10)]).then(async() => {

  console.log('Await');
  let [r1, r2, r3] = [await t1(100), await t1(200), await t1(10)]
});

Так что это не эквивалентно. Подробнее о разнице .

В конце концов, Promise.all - более чистый подход, который лучше масштабируется для произвольного числа задач.

0 голосов
/ 30 октября 2018

На данный момент единственной причиной для использования Promises является вызов нескольких асинхронных заданий с использованием Promise.all() В противном случае вам обычно лучше работать с async / await или Observables.

0 голосов
/ 30 октября 2018

Это зависит от того, с каким подходом вы хороши, и обещание, и async / await хороши, но если вы хотите написать асинхронный код, используя структуру синхронного кода, вы должны использовать подход async / await. Как и в следующем примере, функция возвращает пользователь со стилем Promise или async / await. если мы используем Promise:

function getFirstUser() {
    return getUsers().then(function(users) {
        return users[0].name;
    }).catch(function(err) {
        return {
          name: 'default user'
        };
    });
}

если мы используем aysnc / await

async function getFirstUser() {
    try {
        let users = await getUsers();
        return users[0].name;
    } catch (err) {
        return {
            name: 'default user'
        };
    }
}

Здесь в подходе обещания нам нужна структура, которой можно следовать, и в подходе асинхронности / ожидания мы используем 'await' для удержания выполнения асинхронной функции.

Вы можете проверить эту ссылку для большей ясности. Посетите https://medium.com/@bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8

0 голосов
/ 30 октября 2018

На самом деле это зависит от версии вашего узла, но если вы можете использовать async/await, тогда ваш код будет более читабельным и проще в обслуживании. Когда вы определяете функцию как 'async', она возвращает нативный Promise, а когда вы вызываете ее с помощью await, она выполняет Promise.then.

Примечание: Поместите ваши ожидающие вызовы в try/catch, потому что, если Promise не выполняется, он выдает 'catch', который вы можете обработать внутри блока catch.

try{
let res1 = await your-async-function(parameters);
let res2 = await your-promise-function(parameters);
await your-async-or-promise-function(parameters);
}
catch(ex){
// your error handler goes here
// error is caused by any of your called functions which fails its promise
// this methods breaks your call chain
}

также вы можете справиться со своим «уловом» следующим образом:

let result = await your-asyncFunction(parameters).catch((error)=>{//your error handler goes here});

этот метод не вызывает исключения, поэтому выполнение продолжается.

Я не думаю, что между async/await есть разница в производительности, кроме собственной реализации модуля Promise.

Я бы предложил использовать модуль bluebird вместо встроенного в узел нативного обещания.

...