簡體   English   中英

如何在一個請求中等待,直到另一個請求完成 nodeJS 中相同 function 的執行

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

我正在使用 meteor。 我在鐵路由器中定義了一條路由如下,

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

我想一次生成一張收據。 即收據需要有一個唯一的編號,該編號本質上是遞增的。

現在我正在讀取之前存儲的收據編號並將其加一。 我認為這是當前處理收據的收據編號。

但是,只要不被多個客戶端同時調用generatereceipt API,這就可以正常工作。 當同時調用 API 時,所有同時處理的收據都考慮相同的收據編號。

因此,我想請求檢查相同的 REST API 是否被其他客戶端調用,其他請求正在處理中。 如果它在進程中,那么我想等到它在該請求線程中的執行完成。

我假設這使用某種數據庫/后端來存儲收據 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

使用 async 和 await 來等待一個請求的完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM