0

我正在尝试将 MySQL 查询的输出动态写入存档。这是我的代码:

var async = require("async");
var mysql = require("mysql");
var express = require("express"); 
var archiver = require("archiver");

var app = express();

var connection = mysql.createConnection({
   host     : 'localhost',
   user     : 'root',
   password : 'password',
   database : 'test'
});

app.get('/file', (req, res) => {

    res.writeHead(200, {
        'Content-Type': 'application/zip',
        'Content-disposition': 'attachment; filename=archive-name.zip'

    var zip = archiver('zip', {
        zlib: { level: 9 } 
    });

    zip.pipe(res); 

    zip.on('end', function() {
        console.log('Archive wrote %d bytes', zip.pointer());
    });

    const queriesArray = ["SELECT * FROM tb1", "SELECT * FROM tb2"];

    async.forEachOf(queriesList, (query) => {
        connection.query(query, (err, results) => {
            if(!err) {
                zip.append(JSON.stringify(results), {name: `${query}.txt`})
            }
            else {
                console.log("Error while performing Query");
            }
        })
    }, function(err) {
           if (err) {
               console.log("error")
           }
           else {
               zip.finalize();
           }
       }) 
})

const port = process.env.PORT || 7000;
app.listen(port, () => {
    console.log('Listen on port ' + port);
})

此代码应该创建一个包含多个文本文件的 zip 存档。用户访问/file页面必须显示文件下载提示,但似乎zip.finalize()无法正常工作,因此我无法下载创建的存档(在我访问时开始下载/file但未完成)。为什么我的代码不起作用?

4

1 回答 1

1

这是因为您的回调函数永远不会被调用,因为forEachOf不知道它已完成所有异步任务。

iteratee 函数有一个最终参数,它是一个回调函数,您必须调用它才能知道该特定异步进程已完成,但您从不使用它。

https://caolan.github.io/async/global.html#AsyncFunction

Async 上下文中的“异步函数”是具有可变数量参数的异步函数,最后一个参数是回调。(function (arg1, arg2, ..., callback) {}) 最终回调的形式为callback(err, results...)必须在函数完成后调用。

因此,要修复您的代码,请确保在查询调用的回调中调用 iteratee 函数的回调方法

async.forEachOf(queriesList, (query,key,callback) => {
    connection.query(query, (err, results) => {
        if(!err) {
            zip.append(JSON.stringify(results), {name: `${query}.txt`})
        }
        else {
            console.log("Error while performing Query");
        }
        callback();
    })
于 2018-10-15T16:10:53.627 回答