Javascript 使用PostgreSQL构建逻辑承诺链

Javascript 使用PostgreSQL构建逻辑承诺链,javascript,postgresql,express,promise,ecmascript-6,Javascript,Postgresql,Express,Promise,Ecmascript 6,我是一个新的承诺者,我试图在NodeJS上建立一个承诺逻辑。我有一个API来跟踪工作时间 人们只需输入他们的PIN码就可以打卡进出 API(用于时钟输入部分)所做的是检查数据库(PostgreSQL和pg promise)以查找带有PIN的员工ID。如果PIN无效(未找到任何员工),则拒绝承诺并显示错误消息。然后它必须查找它们的“时钟状态”,以验证它们是否已经进入或退出。可以使用与检索员工ID相同的查询完成。如果已在中,请使用消息拒绝承诺。然后它必须从员工那里查找轮班ID。之后,它将收集轮班信息

我是一个新的承诺者,我试图在NodeJS上建立一个承诺逻辑。我有一个API来跟踪工作时间

人们只需输入他们的PIN码就可以打卡进出

API(用于时钟输入部分)所做的是检查数据库(PostgreSQL和pg promise)以查找带有PIN的员工ID。如果PIN无效(未找到任何员工),则拒绝承诺并显示错误消息。然后它必须查找它们的“时钟状态”,以验证它们是否已经进入或退出。可以使用与检索员工ID相同的查询完成。如果已在中,请使用消息拒绝承诺。然后它必须从员工那里查找轮班ID。之后,它将收集轮班信息以比较时间。 最后,if将在数据库中插入一行,其中包含上一步收集的信息

简言之:

New Promise 
 Get the Employee ID and Clock Status, and Shift ID
Then
 If No Employee found then reject the promise
Then 
 If Clock Status is already in, reject the promise with a different message
Then
 Gather informations for the shift 
Then
 Insert a new row in the WorkHour table using Employee info and Shift informations
我的路由器在这里(使用ExpressJS)

我正试图建立承诺链,但我不想陷入厄运金字塔

clockin: function(pin) {

    // Getting the resourceID from PIN
    var p = new Promise((resolve, reject) => {
        if (pin === undefined) {
            throw new Error('No PIN');
        } else {
            db.any('SELECT id, timeclockstatus From Employee Where PIN =  $1', pin)
            .then((EmployeeInfos) => {
                return (db.any('select id, timeclockstatus from res_resources where id = $1 ', ResourceID[0].id))
            })
//******  I'm stuck here
我想使用ES6的原生承诺。我试着查找示例,但似乎没有一个符合我的要求。也许我错过了什么。。。
有什么建议吗?

以简化的形式,因为您的案例描述中并非所有内容都清楚:

router.post('/clockin', function (req, res) {
    db.task(t=> {
        var pin = req.body.pin;
        if (!pin) {
            throw new Error('No PIN');
        }
        return t.one('SELECT id, timeclockstatus FROM Employee WHERE PIN = $1', pin)
            .then(data=> {
                // return another query request, based on `data`
            })
            .then(data=> {
                // return your insert query as needed, etc...
            });
    })
        .then(data=> {
            // provide successful response;
        })
        .catch(error=> {
            // provide error response;
        });
});

以简化的形式,因为您的案例描述并非所有内容都清楚:

router.post('/clockin', function (req, res) {
    db.task(t=> {
        var pin = req.body.pin;
        if (!pin) {
            throw new Error('No PIN');
        }
        return t.one('SELECT id, timeclockstatus FROM Employee WHERE PIN = $1', pin)
            .then(data=> {
                // return another query request, based on `data`
            })
            .then(data=> {
                // return your insert query as needed, etc...
            });
    })
        .then(data=> {
            // provide successful response;
        })
        .catch(error=> {
            // provide error response;
        });
});

如果你对承诺还不熟悉,那么你陷入困境也就不足为奇了。关键问题是要知道,特别是在最后阶段,您需要员工信息(第一阶段)和轮班信息(第三阶段)

正如您在参考资料中所看到的,可以使用各种方法。其中:

  • “可变上下文状态”是最简单但丑陋的
  • “断链”是一种可能性
  • “嵌套和关闭”是完全可行的,但会给你带来你试图避免的厄运金字塔
  • “明确传递”(各种表述)很好地阐述了承诺,这将是我在这里的选择
这四个阶段的表述略有不同,但性质相同。每个阶段:

  • 做一些异步的事情
  • 将所有以前的结果加上自己的结果传递到主链的成功路径上
  • 沿主链的错误路径传递有意义的错误消息
请注意使用
Promise.all()
和(蓝鸟的)
.spread()
将多个结果提供给下一阶段。本机ES6承诺也可以实现同样的效果,但上面展示的一些简单性将丢失

使用上述代码,“/clockin”路由器功能将是:

router.post('/clockin', function(req, res) {
    //Execute the API
    time.clockin(req.body.pin)
    .spread((employeeInfo, status, shiftData, time) => { res.send(time); })
    .catch((err) => { res.status(500).send(err) }); // any uncaught errors thrown above will percolate down to here.
});

如果你对承诺还不熟悉,那么你陷入困境也就不足为奇了。关键问题是要知道,特别是在最后阶段,您需要员工信息(第一阶段)和轮班信息(第三阶段)

正如您在参考资料中所看到的,可以使用各种方法。其中:

  • “可变上下文状态”是最简单但丑陋的
  • “断链”是一种可能性
  • “嵌套和关闭”是完全可行的,但会给你带来你试图避免的厄运金字塔
  • “明确传递”(各种表述)很好地阐述了承诺,这将是我在这里的选择
这四个阶段的表述略有不同,但性质相同。每个阶段:

  • 做一些异步的事情
  • 将所有以前的结果加上自己的结果传递到主链的成功路径上
  • 沿主链的错误路径传递有意义的错误消息
请注意使用
Promise.all()
和(蓝鸟的)
.spread()
将多个结果提供给下一阶段。本机ES6承诺也可以实现同样的效果,但上面展示的一些简单性将丢失

使用上述代码,“/clockin”路由器功能将是:

router.post('/clockin', function(req, res) {
    //Execute the API
    time.clockin(req.body.pin)
    .spread((employeeInfo, status, shiftData, time) => { res.send(time); })
    .catch((err) => { res.status(500).send(err) }); // any uncaught errors thrown above will percolate down to here.
});

尝试遵循您的伪代码。注意,如果db.any返回承诺,则不需要使用您在发布的代码中使用的承诺构造函数反模式。在知道移位模式之前,如何调用
clockin()
(或
clockout
)?尚不清楚是什么
ResourceID[0]
在您的示例中引用。假设
any
已经返回承诺,您。@Roamer-1888接口已经知道状态,并且调用了正确的方法。请尝试按照伪代码进行操作。注意,如果db.any返回承诺,则不需要使用您在发布的代码中使用的承诺构造函数反模式。在知道移位模式之前,如何调用
clockin()
(或
clockout
)?尚不清楚是什么
ResourceID[0]
在您的示例中引用。鉴于
any
已经返回承诺,您。@Roamer-1888接口已经知道状态,并且调用了正确的方法。谢谢。我用你的例子让我振作起来。我设法让它工作了。谢谢。我用你的例子让我振作起来。我设法让它工作。