caolan / async

Async utilities for node and the browser
http://caolan.github.io/async/
MIT License
28.18k stars 2.41k forks source link

Could author provide a option to choose if use queueMicrotask #1788

Closed Hooho closed 11 months ago

Hooho commented 2 years ago

sorrry to waste your time to read my probleam, and I know my english is not good, so maybe there are some express issues, hope you could understand

I got a problem since I update async to v3.2.1,and I checked the CHNAGELOG and debug my project for a long long long time,and I find the reaseon is that the package use queueMicrotask

the detail is

I use a pkg exceljs to , ant it requires a pkg [ Archiver ], and Archiver require this pkg [async]

image image

when I use exceljs like this

const wb = ExcelJS.stream.xlsx.WorkbookWriter()

.... something

ctx.body = wb.stream

I find the stream is over before I write into all data so that the excel file is error

because in the [koa] ,it use [koa-compose] to execute middleware

image

image

image

koa-compose use Promise.then to set pipe to response

if async use queuMicrotask, it would async.queue execute tasks before koa set body ok , because queueMicrotask is quickly then promise

if async use setImmidate is ok

like this demo

function compose(fn) {
  return Promise.resolve(fn());
}

function middleware() {
  console.log("excute middleware");

  setImmediate(() => {
    console.log("middleware  setImmediate");
  });
  queueMicrotask(() => {
    console.log("middleware  queueMicrotask");
  });
}

compose(middleware).then(() => {
  console.log("link stream");
})

the result is

image

aearly commented 2 years ago

Personally, I feel like this is a bug in ExcellJs or archiver, since this situation relies on the precise ordering of deferrals. One workaround to try:

const wb = ExcelJS.stream.xlsx.WorkbookWriter()

//.... something
const stream = wb.stream // I assume this is a getter
await Promise.resolve() // defer to let the stream begin
ctx.body = stream

Or set your async dep to ~3.1.0.