NodeJS 我是否正确地使用了promisify()和bind()?

de90aj5v  于 2023-05-28  发布在  Node.js
关注(0)|答案(1)|浏览(102)

我正在编写中间件,使用SQLite3和Next.js返回数据库查询。下面是我编写的返回DB表内容的代码片段。它看起来很有效,我对源代码的检查也很可靠,关于bind()的使用的评论褒贬不一。

// route = /dbread
import { NextResponse } from 'next/server';
const sqlite3 = require("sqlite3").verbose();
const util = require('util');

export async function GET(req) {
    const db = new sqlite3.Database("./database.db");
    const dbAll = util.promisify(db.all).bind(db);
    
    let response = await dbAll('SELECT * FROM "text"')
        .then(db.close())
        .catch((err => {
            console.log(err);
            return ['error'];
            }));
    return NextResponse.json(JSON.stringify(response));
}

然而,如果我把绑定拿出来,它就坏了,所以我把它放在里面,即使我不完全理解它在做什么。有没有更好的办法?解决方案似乎很简单,但我只是想确保我踩在坚实的地面上。

iecba09b

iecba09b1#

你用.bind(db)做的工作很好,是一种正确的做事方式。
我更喜欢保持其他方法的调用约定类型,方法如下:

const db = new sqlite3.Database("./database.db");
db.allP = util.promisify(db.all);

然后,你这样称呼它:

db.allP(...)

就像你会调用数据库上的任何其他方法一样,但这只是我个人的偏好。两种方法都行。这种方式调用也将db示例“绑定”到方法调用,因此它可以作为方法中的this正确地使用,以便方法在其实现中使用。
作为解释。当你调用一个方法时,如:

obj.method(...)

这使得obj值在该方法的实现中作为this可用。对于您的数据库实现,这是必要的。
当您执行此操作时:
const dbAll = util.promisify(db.all); dbAll(…)
dbAll()已成为常规函数调用,this的值是全局对象(在非严格模式下)或undefined(如果在严格模式下运行)。因此,dbAll()的实现无法访问db变量,这将使其无法工作。它期望dbthis中。以您所做的方式添加.bind()会强制将this的值设置为db。但是,obj.method()db.allP()中的方法调用会自动为您完成此操作。这就是为什么db.allP()不需要.bind()才能正常工作。
仅供参考,您可能希望使用具有已经支持promise的接口的sql模块,而不是根据需要手动promise单个方法。

相关问题