如何在一个请求中等待另一个请求完成nodeJS中相同功能的执行

How to wait in one request till another request finishes the execution of same function in nodeJS

我正在使用流星。我在 Iron Router 中定义了一条路由,如下所示,

Router.route('/api/generatereceipt', {where: 'server'}).post(function(req, res, next) {
  console.log("API: generatereceipt invoked.");
  const reqBody = req.body;
  ....
}

我想一次生成一张收据。即收据需要有一个唯一的编号,该编号本质上是递增的。

现在我正在读取之前存储的收据编号并将其递增 1。我认为这是当前处理收据的收据编号。

但是,只要 generatereceipt API 没有被多个客户端同时调用,它就可以正常工作。当同时调用API时,所有并发处理的收据都认为是同一个收据号。

因此,我想发出一个请求,检查在处理其他请求时是否有其他客户端调用了相同的 REST API。如果它在进程中,那么我想等到它在该请求线程中的执行完成。

使用 async 和 await 等待一个请求的完成。

我假设这使用某种 database/backend 来存储收据 ID?如果是这样,您应该对数据库使用约束以确保收据 ID 是唯一的。更好的是,为什么不让收据 id 列自动递增,那么你就不需要检查以前的收据编号并自己递增,它将由数据库层处理,它只是作为插入的一部分返回。

如果不需要自增,那么考虑使用UUID即可。

我想不出您想要等待执行的任何原因。它会使您的应用程序对于第一个请求以外的任何人都变慢并且无法扩展。

如果你真的有正当理由以这种方式构建它并自己生成自动增量,那么最好详细解释为什么会这样,因为可能有更好的解决方案然后只是“阻止”下一行

并发请求应该没有问题。请参阅以下示例:

import { Meteor } from 'meteor/meteor'
import { WebApp } from 'meteor/webapp'
import { HTTP } from 'meteor/http'

// create a simple HTTP route

WebApp.connectHandlers.use('/api/generatereceipt', function (req, res, next) {
   // random 0 - 50ms timeout to simulate response delay
  const randomTimeout = Math.floor(Math.random() * 50)

  // use Meteor's Promise.await to await async in non-async functions
  // --> should prevent troubles with legacy iron-router
  const receipt = Promise.await(getReceipt())
  
  setTimeout(() => {
    res.writeHead(200)
    res.end(String(receipt))
  }, randomTimeout)
})

// increment id and return new value
let receiptId = 0
async function getReceipt () {
  return receiptId++
}



Meteor.startup(function () {
  let testCount = 0
  const url = Meteor.absoluteUrl('/api/generatereceipt')

  // simulate concurrent calls by using a timeout of 0
  function call (id) {
    setTimeout(Meteor.bindEnvironment(() => {
      // simulate calling the /api/generatereceipt route
      const response = HTTP.get(url)
      console.log(id, ' => ', response.content) // should match
    }, 0))
  }

  for (let i = 0; i < 25; i++) {
    call(testCount++)
  }
})

如您所见,调用将解析为递增的 ID:

=> Meteor server restarted                    
I20200703-09:59:15.911(2)? 9  =>  9
I20200703-09:59:15.912(2)? 7  =>  7
I20200703-09:59:15.913(2)? 4  =>  4
I20200703-09:59:15.913(2)? 0  =>  0
I20200703-09:59:15.913(2)? 21  =>  21
I20200703-09:59:15.913(2)? 24  =>  24
I20200703-09:59:15.913(2)? 17  =>  17
I20200703-09:59:15.913(2)? 18  =>  18
I20200703-09:59:15.915(2)? 2  =>  2
I20200703-09:59:15.917(2)? 19  =>  19
I20200703-09:59:15.923(2)? 6  =>  6
I20200703-09:59:15.923(2)? 23  =>  23
I20200703-09:59:15.925(2)? 11  =>  11
I20200703-09:59:15.928(2)? 8  =>  8
I20200703-09:59:15.931(2)? 16  =>  16
I20200703-09:59:15.932(2)? 10  =>  10
I20200703-09:59:15.934(2)? 5  =>  5
I20200703-09:59:15.934(2)? 13  =>  13
I20200703-09:59:15.934(2)? 22  =>  22
I20200703-09:59:15.936(2)? 20  =>  20
I20200703-09:59:15.936(2)? 15  =>  15
I20200703-09:59:15.939(2)? 14  =>  14
I20200703-09:59:15.940(2)? 1  =>  1
I20200703-09:59:15.940(2)? 3  =>  3
I20200703-09:59:15.943(2)? 12  =>  12