Правильный способ вызвать асинхронную функцию main?

#javascript #node.js #async-await #node-mysql2

#javascript #node.js #асинхронный-ожидание #узел-mysql2 #async-ожидание

Вопрос:

У меня есть несколько сценариев nodejs, то есть процессов, которые выполняют задание и завершают его, а не выполняются непрерывно.

Я использую асинхронные функции, например:

 const mysql = require('mysql2/promise');
...

async function main() {
    var conn = await mysql.createConnection(config.mysql);
    ...
    var [response, error] = await conn.execute(`
        DELETE something
        FROM some_table
        WHERE field = ?
    `, [value]);
    ...
  

Является ли следующий код:

 main().then(() => process.exit(0)).catch(err => { console.error(err); process.exit(1); });
  

лучший / правильный способ начать выполнение асинхронного кода?

(Это работает, но я хочу убедиться, что я не оставляю никаких пробелов, которые могут вызвать неожиданности, такие как молчаливое проглатывание исключений.)

Почему conn.execute() возвращает error (который мне нужно проверить вручную), а не выбрасывает один?

Ответ №1:

Использование then вместе с async..await не обязательно, потому что это синтаксический сахар для then .

Точкой входа может быть async IIFE (IIAFE):

 (async () => {
  try {
    var conn = await mysql.createConnection(config.mysql);
    ...
    var [response] = await conn.execute(`
        SELECT something
        FROM some_table
        WHERE field = ?
    `, [value]);
    ...
    process.exit(0);
  } catch (err) {
    console.error(err);
    process.exit(1);
  }
})();
  

Также может не потребоваться process.exit(0) , если соединение было закрыто.

Почему conn.execute() возвращает ошибку (которую мне нужно проверить вручную), а не выдает ее?

Это не так и не является обычным для функций с поддержкой promise возвращать ошибку в результате.

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

Как показывает документация, второй элемент является fields и не error :

 const [rows, fields] = await conn.execute('select ? ? as sum', [2, 2]);
  

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

Комментарии:

1. У меня была ошибка вырезания / вставки, запрос был ошибочно ВЫБРАН. Теперь это, правильно, удаление, которое не возвращается [rows, fields] .

2. В настоящее время я не могу проверить, что возвращает execute в случае УДАЛЕНИЯ, но я уверен, что он должен отклонять ошибку, а не разрешать ее, поэтому ее можно перехватить с помощью try .. catch внутри async. Почему вы решили, что она возвращает ошибку, почему conn.execute() возвращает ошибку ?

3. Я только что провел некоторое тестирование, и плохой SQL приводит к возникновению ошибки, а не к возврату. При хорошем SQL возвращаемое значение представляет собой массив из двух элементов [ResultSetHeader, undefined] , что подразумевает, что во второй позиции может быть что-то. Я опубликую другой комментарий…

4. Спасибо за вашу помощь, я принял ваш ответ. Я не могу найти, где я прочитал, что удаления и обновления возвращаются [ResultSetHeader, ошибка] — возможно, я просто предположил это на основе обратных вызовов из неасинхронных функций. Все еще в замешательстве относительно того, что может появиться во второй позиции возвращаемого массива.

Ответ №2:

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

Вы также можете определять асинхронные функции, используя выражение асинхронной функции.

 async function f() {

  try {
    let response = await fetch('http://no-such-url');
  } catch(err) {
    alert(err); // TypeError: failed to fetch
  }
}

f();
  

вы также можете немедленно вызвать функцию асинхронной синхронизации, используя приведенный ниже синтаксис

 (async () => {

})();
  

Комментарии:

1. Это дает мне SyntaxError: await is only valid in async function .

2.Ваш первый пример все еще выглядит плохо. Вы используете nodejs или браузер? У Nodejs нет alert . Если я заменю alert и fetch на функции, которые существуют, я просто получу обещание возвращенное, но не выполненное.

3. Речь идет о том, как вызвать async . Ничего специфичного для узла

4. вы получаете разрешенное значение или отклоненное значение. Пожалуйста, ознакомьтесь с promise подробнее

5. Спасибо за вашу помощь, но, к сожалению, я не вижу этого в nodejs версии 10.15.3. Вы используете nodejs или браузер? Если вы используете nodejs, откуда они fetch и alert берутся.