簡體   English   中英

JavaScript NodeJS 如何在異步函數中使用流/承諾?

[英]JavaScript NodeJS How to use stream/promises with async functions?

我在 Node 中有一個 JS 異步 function。 比如說,它從 URL 下載一個文件並用它做一些事情,例如。 解壓它。 我是這樣寫的,它可以工作,但是eslint告訴我有一股濃濃的代碼味道: error Promise executor functions should not be async no-async-promise-executor 由於正文 function 中的await fetch ,因此需要Async

我對流不夠熟練,也沒有async/await streams自己糾正它。 我想擺脫 Promise 並完全使用async/await 模塊stream/promises似乎是從 Node-15 到 go 的方式,如此處how-to-use-es8-async-await-with-streams所評論。 如何在這種情況下使用await pipeline(...) 也許有更好更短的方法?

這是 function:

function doSomething(url) {
  return new Promise(async (resolve, reject) => {
    try {
      const fileWriteStream = fs.createWriteStream(someFile, {
        autoClose: true,
        flags: 'w',
      });

      const res = await fetch(url);
      const body = res.body;
      body
        .pipe(fileWriteStream)
        .on('error', (err) => {
          reject(err);
        })
        .on('finish', async () => {
          await doWhatever();
          resolve('DONE');
        });
    } catch (err) {
      reject(err);
    }
  });
}

您可以在到達執行程序之前簡單地執行await

async function doSomething(url) {
  
  const fileWriteStream = fs.createWriteStream(someFile, { autoClose: true, flags: 'w' });
  
  let { body } = await fetch(url);
  
  body.pipe(fileWriteStream);
  
  return new Promise((resolve, reject) => {
    body.on('error', reject);
    body.on('finish', resolve);
  });
  
};

我的一般建議是盡可能多地從 promise 執行程序中刪除代碼。 在這種情況下,Promise 只需要捕獲分辨率/拒絕。

請注意,我還從doSomething中刪除doWhatever - 這使得doSomething更加健壯。 你可以簡單地做:

doSomething('http://example.com').then(doWhatever);

最后,我建議您將someFile設置為doSomething的參數,而不是從更廣泛的上下文中引用它!

要使用您正在尋找的pipeline function,它將是

const { pipeline } = require('stream/promises');

async function doSomething(url) {
  const fileWriteStream = fs.createWriteStream(someFile, {
    autoClose: true,
    flags: 'w',
  });

  const res = await fetch(url);
  await pipeline(res.body, fileWriteStream);
  await doWhatever();
  return 'DONE';
}

您可以在 NodeJS 中使用fs/promises並將您的代碼縮減為以下內容:

import { writeFile } from 'fs/promises'

async function doSomething(url) {
    const res = await fetch(url);
    if (!res.ok) throw new Error('Response not ok');
    await writeFile(someFile, res.body, { encoding: 'utf-8'})
    await doWhatever();
    return 'DONE';
  });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM