प्रौद्योगिकी साझेदारी

अग्रभागः समवर्तीनिवेदनानि कथं नियन्त्रयति

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

कदा अग्रभागस्य समवर्ती अनुरोधं नियन्त्रयितुं आवश्यकं भवति?यदा आवश्यकदत्तांशस्य अनुरोधाय बहुवारं समयः भवति । यथा, यदि अन्तरफलकं एकस्मिन् समये बृहत् परिमाणं दत्तांशं प्रत्यागच्छति तर्हि ब्राउजर् रेण्डरिंग् अथवा क्रैश अपि अटति अस्मिन् समये वयं एकस्मिन् समये 6 अनुरोधाः बैच् मध्ये निर्गन्तुं शक्नुमः, येन अटन् अथवा क्रैश न भवति .

अतः अग्रभागः समवर्ती अनुरोधं कथं नियन्त्रयति ?

समवर्ती अनुरोधानाम् अग्रभागनियन्त्रणार्थं मुख्यविचाराः

यथा - यदि २० अनुरोधाः सन्ति तर्हि भवद्भिः अनुसरणं कर्तव्यम् 3 प्रथमसमूहस्य अनुरोधं सम्पन्नं कृत्वा द्वितीयसमूहः अनुरोधितः भविष्यति इत्यादि ।

मुख्यविचारः अस्ति यत् अनुरोधविधिं अनुरोधमापदण्डान् च सरणीयां संग्रहीतुं, ततः एकैकं 3 अनुरोधयितुं, ततः अनुरोधस्य समाप्तेः अनन्तरं अग्रिमस्य 3 इत्यस्य अनुरोधं कर्तुं च प्रत्येकं अनुरोधसमूहस्य प्रत्यागमनानन्तरं परिणामाः रक्षिताः भवन्ति, सर्वेषां अनुरोधानाम् प्रत्यागमनानन्तरं सर्वे परिणामाः प्रत्यागच्छन्ति ।

api design

pControl : समवर्ती अनुरोधनियन्त्रकः, समवर्तीनां अधिकतमसङ्ख्यां पारयन्;
add : अनुरोधं पैरामीटर् च योजयन्तु;
start : अनुरोधं आरभत, प्रतिज्ञां प्रत्यागच्छतु, अनुरोधः समाप्तः जातः ततः परं पारयन्तु.then सर्वाणि परिणामानि प्राप्नुवन्तु;

संहिता

function pControl(limit) {
  const taskQueue = [] // {task: Function, params: any[]}[]
  return {
    add,
    start
  }

  function add(task, params) {
    taskQueue.push({
      task,
      params
    })
  }

  function start() {
    return runAllTasks()
  }

  function runAllTasks() {
    const allResults = []
    return new Promise((resolve) => {

      runTask()

      function runTask() {
        if (taskQueue.length === 0) {
          // 递归结束
          return resolve(allResults)
        }
        const needRunSize = Math.min(taskQueue.length, limit)
        const tasks = taskQueue.splice(0, needRunSize)
        const promises = tasks.map(({
          task,
          params
        }) => task(params))
        Promise.all(promises).then((resList) => {
          allResults.push(...resList)
          // NOTE 递归调用的位置很关键
          runTask()
        })
      }
    })
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

कील कोड व्याख्या

  • pControl: एतत् फंक्शन् युक्तं वस्तु प्रत्यागच्छति add तथाstart विधिद्वयम्, २.add कार्याणि मापदण्डानि च योजयितुं प्रयुक्तम्,start अनुरोधस्य आरम्भार्थं प्रयुक्तः, एतत् समापनम् अस्ति ।

  • runAllTasks: प्रत्यागच्छति apromise, ततः चnew Promiseआन्तरिकरूपेण पुनरावर्तनीयरूपेण निष्पादितम्runTask, runTask उत्तीर्णं भवतिPromise.all इत्यस्मिन् समवर्ती अनुरोधाः निष्पादयन्तुPromise.all().then() पुनः आह्वयतुrunTask, प्रत्यागन्तुं अनुरोधानाम् एकं समुच्चयं कार्यान्वितं कुर्वन्तु, ततः द्वितीयं अनुरोधसमूहं निष्पादयन्तु ।

समूहप्रतीक्षायाः साक्षात्कारस्य कुञ्जी अस्ति यत्... .then पुनरावर्तनीय आह्वान।

चिन्तनम् : runAllTasks लूप् इत्यस्य उपयोगेन कार्यान्वितुं शक्यते वा?

आम्, उपयोगस्य आवश्यकता अस्ति async 和 for 循环 + await

async function runAllTasks2() {
  const allResults = []
  const groupArr = []
  let startIndex = 0
  // 划分分组
  while (startIndex < taskQueue.length) {
    const arr = taskQueue.slice(startIndex, startIndex + limit)
    groupArr.push(arr)
    startIndex += limit
  }
  for (let index = 0; index < groupArr.length; index++) {
    const pList = groupArr[index].map(({
      task,
      params
    }) => task(params))
    const res = await Promise.all(pList)
    allResults.push(...res)
  }
  return allResults
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

for loop इत्यस्मिन् उपयोक्तुं न शक्यते .then , अन्यथा अग्रिमः पाशः पूर्वपाशं न प्रतीक्षते ।

उपयुञ्जताम्‌ for of पुनरावर्तनीयं कार्यान्वयनम् : १.

async function runAllTasks2() {
  const allResults = []
  const groupArr = []
  let startIndex = 0
  // 划分分组
  while (startIndex < taskQueue.length) {
    const arr = taskQueue.slice(startIndex, startIndex + limit)
    groupArr.push(arr)
    startIndex += limit
  }
  // 迭代分组
  const it = groupArr.entries()
  for (const [key, value] of it) {
    const pList = value.map(({
      task,
      params
    }) => task(params))
    const res = await Promise.all(pList)
    allResults.push(...res)
  }
  return allResults
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

लूप्स् तथा Promise इत्येतयोः एकत्र उपयोगः कथं करणीयः ?

forwhilefor...of अनिवार्यपाशसंरचनानां कृते यदि भवान् लूप् मध्ये प्रतीक्षाप्रभावं प्राप्तुम् इच्छति तर्हि भवता अवश्यमेव उपयोगः करणीयःasync लूप् मध्ये function wrapperawait ,सेवातः बहिः.then

forEachmapfilter एतादृशाः कार्यात्मकपाशसंरचनाः प्रतीक्षाप्रभावानाम् समर्थनं न कुर्वन्ति, यतः एतानि कार्यात्मकपाशसंरचनानि समकालिकाः सन्ति, प्रतीक्षायाः समर्थनं न कुर्वन्ति ।

async तथा循环 + await पाशयोः मध्ये प्रतीक्षाप्रभावं प्राप्तुं संयुक्तम् ।

promise.then तथा递归 पाशयोः मध्ये प्रतीक्षाप्रभावं प्राप्तुं संयुक्तम् ।

एपिआइ इत्यस्य उपयोगः सुलभः भवतु इति सुधारयन्तु

  1. पूर्वनिर्धारितमापदण्डान् सेट् कुर्वन्तु: givepControlउपयुक्तं पूर्वनिर्धारितं मूल्यं सेट् कुर्वन्तु, सेट् कुर्वन्तु6, यतः समानं डोमेननाम अस्ति, ब्राउजर् इत्यस्य समवर्ती अनुरोधाः 6 भवन्ति ।
  2. start to callback: callback इत्यस्य माध्यमेन भवान् प्रत्येकस्य समूहस्य अनुरोधपरिणामान् प्राप्तुं शक्नोति तथा च वर्तमानकाले सम्पन्नानां अनुरोधानाम् संख्यां ज्ञातुं शक्नोति।

एतौ सुधारौ सरलौ स्तः। प्रथमं प्रयोगं पश्यामः : १.

const asyncTaskControl = pControl() // 默认 6 
asyncTaskControl.add(task, params1)
asyncTaskControl.add(task, params2)
// ...
asyncTaskControl.add(task, params10)

asyncTaskControl.start((res, doneSize) => {
  // 获取每组请求的结果 和当前完成了多少请求
  console.log(res) // [{index:number,result:data}] 
  console.log(doneSize)
}).then(allResults => {
  // 所有请求结果
  console.log(allResults)
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

आरम्भ-कॉलबैक् किं करोति ?

वर्तमानसमवर्ती-अनुरोधानाम् परिणामान् प्राप्तुं, समाप्ति-प्रगतेः गणनां च उपयोक्तृभ्यः सुलभम् अस्ति ।

उपर्युक्तकार्यं मध्ये समाहितं कुर्वन्तु p-control npm संकुलविमोचनम्

npm: प-नियन्त्रणम्

सुलभः npm i p-control डाउनलोड् कृत्वा उपयोगं कुर्वन्तु।

संक्षेपः

  • .then अतुल्यकालिककार्ययोः मध्ये प्रतीक्षां प्राप्तुं पुनरावृत्त्या सह संयुक्तम्;
  • forwhileपाशं प्रतीक्ष्य चasync + awaitअतुल्यकालिककार्ययोः मध्ये प्रतीक्षां प्राप्तुं संयोजनेन उपयुज्यते;
  • उपयुञ्जताम्‌Promise.allसमवर्तीरूपेण निष्पादनार्थं बहुविधं अतुल्यकालिककार्यं कार्यान्वितं कुर्वन्तु।