Как правильно дождаться возврата перед выполнением какого-либо действия?

#javascript

#javascript

Вопрос:

Я борюсь с некоторыми функциями ожидания / асинхронности. Итак, у меня есть следующая функция, которая pdfData никогда не отличается от undefined ; Что я хочу сделать, так это то, что после всего процесса создания файла pdf подпишите его с помощью s3, загрузите его в s3, затем удалите его из папки temp, чтобы вернуть статус и URL для загрузки.

Кто-нибудь может сообщить мне, чего мне не хватает?

 const pdfData = await pdf
  .create(content, options)
  .toFile(`./src/services/temp/${fileName}`, async function(error, result) {
    if (error) return console.log(error);

    const file = result.filename;
    // requestSignS3
    const awsSign = await signS3(
      `statements/${fileName}`,
      "application/pdf"
    );
    // upload document to S3
    const uploadStatus = await uploadDocumentToS3(awsSign, file);
    // delete file from temp folder
    fs.unlink(file, err => {
      if (err) throw err;
    });
    // set data to return
    const data = {
      status: uploadStatus,
      url: awsSign.url
    };

    return data;
  });

console.log(pdfData);
  

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

1. Просто вопрос проверки работоспособности… вы await pdf ... внутри асинхронной функции?

2. да, вся эта функция находится внутри try catch

3. ?? Попытка / улов не является асинхронной функцией

4. Да, извините, try catch заключен в асинхронную функцию

Ответ №1:

Я вижу рецепт promise (или async-await), смешанный с рецептом обратного вызова. Не делайте этого.

  1. toFile Возвращает обещание? Если это так, то мы в значительной степени уже там:
 const pdfFile = await pdf
  .create(content, options)
  .toFile(`./src/services/temp/${fileName}`);

const pdfData = await /* everything async you want to do with pdfFile goes there */(pdfFile);
  
  1. Если toFile не возвращает обещание, вам нужно подтвердить его либо с помощью promisify библиотеки, либо вручную. В основном это выглядело бы так:
 const toFilePromise = new Promise(function(reject, resolve) => {
    pdf.create(content, options)
        .toFile(`./src/services/temp/${fileName}`, function(error, result) {
            if (error) {
                reject(error);
            } else {
                resolve(result);
            }
        })
});
  

Теперь toFilePromise — это то, чего можно ожидать. После этого вы можете извлечь filename, await signS3( и т.д.

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

1. итак, я использую html-pdf для рендеринга рулей в pdf, и .toFile я вижу, что это происходит в двух параметрах export interface CreateResult { toBuffer(callback: (err: Error, buffer: Buffer) => void): void; toFile(callback: (err: Error, res: FileInfo) => void): void; toFile(filename?: string, callback?: (err: Error, res: FileInfo) => void): void; toStream(callback: (err: Error, stream: fs.ReadStream) => void): void; }

2. Отредактировано с более подробной информацией.