নোড.জেএস-এ সিঙ্ক্রোনাস অনুরোধ


99

ধারাবাহিক ক্রমে আমাকে যদি 3 টি এইচপি এপিআই কল করতে হয় তবে নীচের কোডটির থেকে ভাল বিকল্পটি কী হতে পারে:

http.get({ host: 'www.example.com', path: '/api_1.php' }, function(res) { 
  res.on('data', function(d) { 

    http.get({ host: 'www.example.com', path: '/api_2.php' }, function(res) { 
      res.on('data', function(d) { 

        http.get({ host: 'www.example.com', path: '/api_3.php' }, function(res) { 
          res.on('data', function(d) { 


          });
        });
        }
      });
    });
    }
  });
});
}

এটি পরিষ্কার করা ছাড়া অন্য, আমি মনে করি না আপনি এর চেয়ে ভাল করতে পারেন।
এইচভিগোটকোডস

4
কেন তারা ক্রমযুক্ত হতে হবে?
রায়নস

11
@ রায়নোস এপিআই_2
তে

9
এটি উল্লেখযোগ্য যে ফিউচারগুলি বেশ অবহেলিত, ব্লুবার্ড বা কিউ এর মতো একটি নতুন লাইব্রেরি ব্যবহার করার কথা বিবেচনা করুন
বেনজমিন গ্রুয়েনবুম

4
শিরোনাম এবং প্রশ্ন একে অপরের বিরোধিতা করে। আপনি আপনার প্রশ্নে একটি সুসংগত অনুরোধ বর্ণনা করছেন না তবে অনুরোধের ক্রম, যা সাধারণত প্রতিটি সংক্ষিপ্ত আকারে ঘটে। বড় পার্থক্য - একটি সিঙ্ক্রোনাস কল ব্লক, এবং অ্যাসিঙ্ক্রোনাস ক্রিয়াকলাপ ক্রিয়াকলাপ অবরুদ্ধ করে না (ইউআই অবরুদ্ধ করুন, অন্যান্য অনুরোধগুলি পরিচালনা করতে সার্ভারকে অবরুদ্ধ করুন)। sync-requestগ্রন্থাগারের উল্লেখ করার জন্য নীচে একটি উত্তর রয়েছে , যা এই প্রশ্নের শিরোনামের একটি ভাল উত্তর, তবে প্রশ্নের কোডটি কী বোঝায় তার কোনও উত্তর নয়। প্রতিশ্রুতি সম্পর্কে নীচের উত্তর এর জন্য আরও ভাল উত্তর। আপনি কোনটি বোঝাতে চেয়েছিলেন?
জেক

উত্তর:


69

স্থগিতকরণগুলি ব্যবহার করে Futures

var sequence = Futures.sequence();

sequence
  .then(function(next) {
     http.get({}, next);
  })
  .then(function(next, res) {
     res.on("data", next);
  })
  .then(function(next, d) {
     http.get({}, next);
  })
  .then(function(next, res) {
    ...
  })

আপনার যদি স্কোপ পাস করার প্রয়োজন হয় তবে ঠিক এর মতো কিছু করুন

  .then(function(next, d) {
    http.get({}, function(res) {
      next(res, d);
    });
  })
  .then(function(next, res, d) { })
    ...
  })

অনুগ্রহ করে নোডেজগুলির জন্য অপেক্ষা এবং মুলতুবি সরবরাহ করে এমন আইসডকফসস্ক্রিপ্ট চেষ্টা করুন।
থানিগেইনাথন

এটি কি অবরুদ্ধ? আমি বলতে চাইছি এটি পরের ফাংশনের জন্য লাইনে অবরুদ্ধ হচ্ছে তবে এটি অন্যান্য অ্যাসিঙ্ক ফাংশনগুলির কার্য সম্পাদনকে অবরুদ্ধ করবে না, তাই না?
Oktav

4
হ্যাঁ, স্থগিত পদ্ধতিগুলি অ-ব্লকিং / অ্যাসিঙ্ক are
dvlsg

4
ES6 প্রতিশ্রুতি এপিআই এর কার্যকরভাবে এটি প্রতিস্থাপন করা উচিত, এমনকি "ফিউচারস" এর লেখকের মতে
আলেকজান্ডার মিলস

ফিউচারগুলি খুব পুরানো এবং অবচয়হীন। পরিবর্তে কি দেখুন।
জিম আহো

53

আমি রায়নোসের সমাধানটিও পছন্দ করি তবে আমি একটি ভিন্ন প্রবাহ নিয়ন্ত্রণ গ্রন্থাগার পছন্দ করি।

https://github.com/caolan/async

পরবর্তী প্রতিটি কার্যক্রমে আপনার ফলাফলের প্রয়োজন কিনা তার উপর নির্ভর করে আমি হয় সিরিজ, সমান্তরাল বা জলপ্রপাত ব্যবহার করব।

সিরিজগুলি যখন ক্রমিকভাবে সম্পাদন করতে হয় তবে আপনার পরবর্তী প্রতিটি ফাংশন কলের ফলাফলের প্রয়োজন হবে না।

সমান্তরালে যদি এগুলি সমান্তরালভাবে সম্পাদন করা যায় তবে প্রতিটি সমান্তরাল ফাংশন চলাকালীন আপনার প্রত্যেকের থেকে ফলাফলের প্রয়োজন হয় না এবং সমস্ত শেষ হয়ে গেলে আপনার কলব্যাকের প্রয়োজন হয়।

জলপ্রপাত যদি আপনি প্রতিটি ফাংশনে ফলাফলগুলি আকারে দেখতে চান এবং পরবর্তীটিতে পাস করতে চান

endpoints = 
 [{ host: 'www.example.com', path: '/api_1.php' },
  { host: 'www.example.com', path: '/api_2.php' },
  { host: 'www.example.com', path: '/api_3.php' }];

async.mapSeries(endpoints, http.get, function(results){
    // Array of results
});

9
var http = প্রয়োজনীয় ('http');
এলে মুন্ডি

7
হাহ। উদাহরণ.কম আসলে এই ধরণের জিনিসটির জন্য ডিজাইন করা একটি ডোমেন। কি দারুন.
meawoppl

Async.series কোডটি কমপক্ষে async v0.2.10 হিসাবে কাজ করে না। সিরিজ () কেবল দুটি আর্গুমেন্ট অবধি গ্রহণ করে এবং প্রথম আর্গুমেন্টের উপাদানগুলিকে ফাংশন হিসাবে কার্যকর করবে, সুতরাং অ্যাসিঙ্কটি বস্তুগুলিকে ফাংশন হিসাবে চালানোর চেষ্টা করতে ত্রুটি নিক্ষেপ করে।
ঢাকনা

4
EachAsync ( github.com/FuturesJS/forEachAsync ) ব্যবহার করে এই কোডটির উদ্দেশ্যে যা কিছু করা হয়েছে তার অনুরূপ আপনি কিছু করতে পারেন ।
ঢাকনা

এটি আমি যা চেয়েছিলাম ঠিক তেমন করে। ধন্যবাদ!
aProperFox

33

আপনি আমার সাধারণ নোড লাইব্রেরি ব্যবহার করে এটি করতে পারেন :

function get(url) {
  return new (require('httpclient').HttpClient)({
    method: 'GET',
      url: url
    }).finish().body.read().decodeToString();
}

var a = get('www.example.com/api_1.php'), 
    b = get('www.example.com/api_2.php'),
    c = get('www.example.com/api_3.php');

4
বোকা, আমি এটা কাজ করবে ভেবে require(...).HttpClient is not a constructor
উত্থিত

31

সিঙ্ক-অনুরোধ

এখন পর্যন্ত আমি খুঁজে পেয়েছি এবং ব্যবহার করা সবচেয়ে সহজতমটি হ'ল সিঙ্ক-অনুরোধ এবং এটি নোড এবং ব্রাউজার উভয়কেই সমর্থন করে!

var request = require('sync-request');
var res = request('GET', 'http://google.com');
console.log(res.body.toString('utf-8'));

এটি কোনও পাগল কনফিগারেশন, কোনও জটিল lib ইনস্টল করা হয়নি, যদিও এটিতে একটি lib ফ্যালব্যাক রয়েছে। শুধু কাজ করে। আমি এখানে অন্যান্য উদাহরণ চেষ্টা করেছি এবং যখন স্ট্যাম্পড হয়ে গিয়েছিলাম যখন করার জন্য অতিরিক্ত অতিরিক্ত সেটআপ ছিল বা ইনস্টলগুলি কাজ করে না!

মন্তব্য:

সিঙ্ক-অনুরোধটি যে উদাহরণটি ব্যবহার করে তা যখন আপনি ব্যবহার করবেন তখন দুর্দান্ত খেলবে নাres.getBody() , সমস্ত বডি পান যা একটি এনকোডিং গ্রহণ করে প্রতিক্রিয়া ডেটা রূপান্তর করে। কেবল res.body.toString(encoding)পরিবর্তে না।


আমি দেখতে পেলাম যে সিঙ্ক-অনুরোধটি খুব ধীর গতির .. আমি অন্য একটি github.com/dhruvbird/http-sync ব্যবহার করে শেষ করেছি যা আমার ক্ষেত্রে 10 গুণ দ্রুত।
ফিলিপ স্পিরিডনভ

এর জন্য আমার কোনও ধীর গতি নেই। এটি একটি শিশু প্রক্রিয়া তৈরি করে। আপনার সিস্টেমটি কতটি সিপাস ব্যবহার করে এবং আপনি নোডের কোন সংস্করণ ব্যবহার করছেন? আমি সুইচ প্রয়োজন কিনা তা নির্ধারণ করতে আমি জানতে আগ্রহী।
জিমিলোই

আমি ফিলিপের সাথে একমত, এটি আস্তে আস্তে।
র‌্যাম্বো 7

একই জিনিস আমি ফ্লিপ জিজ্ঞাসা করেছি কিন্তু কোনও প্রতিক্রিয়া পাইনি: আপনার সিস্টেমে কয়টি সিপাস ব্যবহার করেন এবং নোডের কোন সংস্করণ আপনি ব্যবহার করছেন?
জিমিলোই

এটি একটি গুরুতর পরিমাণ সিপিইউ ব্যবহার করে, উত্পাদন ব্যবহারের জন্য প্রস্তাবিত নয়।
ময়েসকুল

20

আমি এপিএসের তালিকা সহ একটি পুনরাবৃত্ত ফাংশন ব্যবহার করব

var APIs = [ '/api_1.php', '/api_2.php', '/api_3.php' ];
var host = 'www.example.com';

function callAPIs ( host, APIs ) {
  var API = APIs.shift();
  http.get({ host: host, path: API }, function(res) { 
    var body = '';
    res.on('data', function (d) {
      body += d; 
    });
    res.on('end', function () {
      if( APIs.length ) {
        callAPIs ( host, APIs );
      }
    });
  });
}

callAPIs( host, APIs );

সম্পাদনা: অনুরোধ সংস্করণ

var request = require('request');
var APIs = [ '/api_1.php', '/api_2.php', '/api_3.php' ];
var host = 'www.example.com';
var APIs = APIs.map(function (api) {
  return 'http://' + host + api;
});

function callAPIs ( host, APIs ) {
  var API = APIs.shift();
  request(API, function(err, res, body) { 
    if( APIs.length ) {
      callAPIs ( host, APIs );
    }
  });
}

callAPIs( host, APIs );

সম্পাদনা: অনুরোধ / অ্যাসিঙ্ক সংস্করণ

var request = require('request');
var async = require('async');
var APIs = [ '/api_1.php', '/api_2.php', '/api_3.php' ];
var host = 'www.example.com';
var APIs = APIs.map(function (api) {
  return 'http://' + host + api;
});

async.eachSeries(function (API, cb) {
  request(API, function (err, res, body) {
    cb(err);
  });
}, function (err) {
  //called when all done, or error occurs
});

আমার অনুরোধগুলির (60 টি আইটেম এবং বর্ধমান) অনুরোধের একটি পরিবর্তনশীল তালিকা রয়েছে বলে আমি এই পদ্ধতিটি নিযুক্ত করেছি। এটি বলেছিল যে আপনার কোডটিতে একটি সমস্যা আছে: যদি API এর আউটপুট অংশের আকারের চেয়ে বেশি হয় তবে 'ডেটা' ইভেন্টটি অনুরোধ অনুযায়ী একাধিক বার নির্গত হবে। আপনি যেমন ডেটা "বাফার" করতে চান: var বডি = ''; res.on ('ডেটা', ফাংশন (ডেটা) {বডি + = ডেটা;})। on ('শেষ', ফাংশন () {কলব্যাক (বডি); যদি (এপিআইএস. দৈর্ঘ্য) কলএপিআই (হোস্ট, এপিআই); );
অঙ্কিত আগরওয়াল

আপডেট হয়েছে। আমি কেবল দেখাতে চাইছিলাম যে পুনরাবৃত্তির মাধ্যমে কীভাবে সমস্যাটিকে আরও সহজ / আরও নমনীয় করা যায়। ব্যক্তিগতভাবে আমি সর্বদা এই ধরণের জিনিসটির জন্য অনুরোধ মডিউলটি ব্যবহার করি কারণ এটি আপনাকে একাধিক কলব্যাকগুলি সহজেই এড়াতে দেয়।
জেনারেলেনি

@ জেনারেলেনরি, আমি অনুরোধের মডিউলটি ব্যবহার করতে চাইলে আমি কীভাবে এটি করব? আপনি কি একটি কোড স্নিপেট অফার করতে পারেন যা উপরেরটি ব্যবহার করে অনুরোধটি অর্জন করে?
স্কোটি

আমি একটি অনুরোধ সংস্করণ এবং একটি অনুরোধ / async সংস্করণ যুক্ত করেছি।
জেনারেলেনারি

5

দেখে মনে হচ্ছে এই সমস্যার সমাধান কখনও শেষ নয়, এখানে আরও একটি :)

// do it once.
sync(fs, 'readFile')

// now use it anywhere in both sync or async ways.
var data = fs.readFile(__filename, 'utf8')

http://alexeypetrushin.github.com/synchronize


আপনি যে লাইব্রেরিটি করেছেন এটি ওপির সমস্যার সমাধান দেওয়ার প্রস্তাব দিলেও, উদাহরণস্বরূপ, fs.readFile সর্বদা সিঙ্ক থাকে।
এরিক

4
নাহ, আপনি স্পষ্টভাবে কলব্যাক সরবরাহ করতে পারেন এবং আপনি যদি চান তবে এটি অ্যাসিক্রোনাস সংস্করণ হিসাবে ব্যবহার করতে পারেন।
অ্যালেক্স ক্রাফট

4
উদাহরণটি হ'ল এইচটিপি অনুরোধের জন্য, ফাইল সিস্টেম যোগাযোগের জন্য নয়।
শেঠ

5

আর একটি সম্ভাবনা হ'ল একটি কলব্যাক সেট আপ করা যা সম্পন্ন কাজগুলি ট্র্যাক করে:

function onApiResults(requestId, response, results) {
    requestsCompleted |= requestId;

    switch(requestId) {
        case REQUEST_API1:
            ...
            [Call API2]
            break;
        case REQUEST_API2:
            ...
            [Call API3]
            break;
        case REQUEST_API3:
            ...
            break;
    }

    if(requestId == requestsNeeded)
        response.end();
}

তারপরে প্রত্যেককে কেবল একটি আইডি নির্ধারণ করুন এবং সংযোগটি বন্ধ করার আগে কোন কাজগুলি সম্পন্ন করতে হবে তার জন্য আপনি আপনার প্রয়োজনীয়তা সেট আপ করতে পারেন।

const var REQUEST_API1 = 0x01;
const var REQUEST_API2 = 0x02;
const var REQUEST_API3 = 0x03;
const var requestsNeeded = REQUEST_API1 | REQUEST_API2 | REQUEST_API3;

ঠিক আছে, এটি সুন্দর নয়। সিক্যুয়ালি কল করার এটি অন্য একটি উপায়। দুর্ভাগ্যজনক যে নোডজেএস সর্বাধিক বেসিক সিঙ্ক্রোনাস কল সরবরাহ করে না। কিন্তু আমি বুঝতে পারি লুন্ঠন কী অ্যাসিঙ্ক্রোনসিটির।


4

পর্যায়ক্রমে ব্যবহার করুন।

sudo এনপিএম ইনস্টল করুন মজাদার

বা

https://github.com/AndyShin/sequenty

খুব সহজ.

var sequenty = require('sequenty'); 

function f1(cb) // cb: callback by sequenty
{
  console.log("I'm f1");
  cb(); // please call this after finshed
}

function f2(cb)
{
  console.log("I'm f2");
  cb();
}

sequenty.run([f1, f2]);

এছাড়াও আপনি এটির মতো একটি লুপ ব্যবহার করতে পারেন:

var f = [];
var queries = [ "select .. blah blah", "update blah blah", ...];

for (var i = 0; i < queries.length; i++)
{
  f[i] = function(cb, funcIndex) // sequenty gives you cb and funcIndex
  {
    db.query(queries[funcIndex], function(err, info)
    {
       cb(); // must be called
    });
  }
}

sequenty.run(f); // fire!

4

2018 পর্যন্ত এবং ES6 মডিউল এবং প্রতিশ্রুতি ব্যবহার করে আমরা এর মতো একটি ফাংশন লিখতে পারি:

import { get } from 'http';

export const fetch = (url) => new Promise((resolve, reject) => {
  get(url, (res) => {
    let data = '';
    res.on('end', () => resolve(data));
    res.on('data', (buf) => data += buf.toString());
  })
    .on('error', e => reject(e));
});

এবং তারপরে অন্য মডিউলে

let data;
data = await fetch('http://www.example.com/api_1.php');
// do something with data...
data = await fetch('http://www.example.com/api_2.php');
// do something with data
data = await fetch('http://www.example.com/api_3.php');
// do something with data

কোডটি একটি অ্যাসিনক্রোনাস প্রসঙ্গে ( asyncকীওয়ার্ড ব্যবহার করে ) কার্যকর করা দরকার


3

অনুরোধের লাইব্রেরি ব্যবহার করে ক্রাফ্টটি হ্রাস করতে সহায়তা করতে পারে:

var request = require('request')

request({ uri: 'http://api.com/1' }, function(err, response, body){
    // use body
    request({ uri: 'http://api.com/2' }, function(err, response, body){
        // use body
        request({ uri: 'http://api.com/3' }, function(err, response, body){
            // use body
        })
    })
})

তবে সর্বাধিক চমকপ্রদতার জন্য আপনার স্টেপের মতো কিছু নিয়ন্ত্রণ-প্রবাহের গ্রন্থাগারটি চেষ্টা করা উচিত - এটি আপনাকে গ্রহণযোগ্য বলে ধরে নিয়ে অনুরোধগুলিকে সমান্তরাল করে তুলবে:

var request = require('request')
var Step    = require('step')

// request returns body as 3rd argument
// we have to move it so it works with Step :(
request.getBody = function(o, cb){
    request(o, function(err, resp, body){
        cb(err, body)
    })
}

Step(
    function getData(){
        request.getBody({ uri: 'http://api.com/?method=1' }, this.parallel())
        request.getBody({ uri: 'http://api.com/?method=2' }, this.parallel())
        request.getBody({ uri: 'http://api.com/?method=3' }, this.parallel())
    },
    function doStuff(err, r1, r2, r3){
        console.log(r1,r2,r3)
    }
)

2

আমি - নিয়ন্ত্রণ প্রবাহ লাইব্রেরি প্রচুর আছে conseq (... কারণ আমি এটা লিখেছিলেন।) এ ছাড়া, on('data')বেশ কয়েকবার গুলি তাই মত গ্রন্থাগার মোড়কের বিশ্রাম ব্যবহার করতে পারেন restler

Seq()
  .seq(function () {
    rest.get('http://www.example.com/api_1.php').on('complete', this.next);
  })
  .seq(function (d1) {
    this.d1 = d1;
    rest.get('http://www.example.com/api_2.php').on('complete', this.next);
  })
  .seq(function (d2) {
    this.d2 = d2;
    rest.get('http://www.example.com/api_3.php').on('complete', this.next);
  })
  .seq(function (d3) {
    // use this.d1, this.d2, d3
  })

2

রায়নোস এটির উত্তর দিয়েছেন। তবুও উত্তর পোস্ট হওয়ার পরে সিক্যুয়েন্স লাইব্রেরিতে পরিবর্তন হয়েছে।

ক্রম ক্রমটি পেতে, এই লিঙ্কটি অনুসরণ করুন: https://github.com/FuturesJS/sequence/tree/9daf0000289954b85c0925119821752fbfb3521e

এইভাবে আপনি এটি পরে কাজ পেতে পারেন npm install sequence:

var seq = require('sequence').Sequence;
var sequence = seq.create();

seq.then(function call 1).then(function call 2);

1

এখানে @ অ্যান্ডি-শিনের আমার সংস্করণটি যুক্তিযুক্ত সূত্রের পরিবর্তে অ্যারে যুক্ত যুক্ত রয়েছে:

function run(funcs, args) {
    var i = 0;
    var recursive = function() {
        funcs[i](function() {
            i++;
            if (i < funcs.length)
                recursive();
        }, args[i]);
    };
    recursive();
}

1

... 4 বছর পরে ...

এখানে ড্যানফ ফ্রেমওয়ার্কটি সহ একটি মূল সমাধান রয়েছে (আপনার এই ধরণের জিনিসগুলির জন্য কোনও কোডের দরকার নেই, কেবল কয়েকটি কনফিগারেশন):

// config/common/config/sequences.js

'use strict';

module.exports = {
    executeMySyncQueries: {
        operations: [
            {
                order: 0,
                service: 'danf:http.router',
                method: 'follow',
                arguments: [
                    'www.example.com/api_1.php',
                    'GET'
                ],
                scope: 'response1'
            },
            {
                order: 1,
                service: 'danf:http.router',
                method: 'follow',
                arguments: [
                    'www.example.com/api_2.php',
                    'GET'
                ],
                scope: 'response2'
            },
            {
                order: 2,
                service: 'danf:http.router',
                method: 'follow',
                arguments: [
                    'www.example.com/api_3.php',
                    'GET'
                ],
                scope: 'response3'
            }
        ]
    }
};

orderসমান্তরালভাবে আপনি কার্যকর করতে চান এমন ক্রিয়াকলাপগুলির জন্য একই মানটি ব্যবহার করুন ।

আপনি যদি আরও খাটো হতে চান তবে আপনি সংগ্রহ প্রক্রিয়াটি ব্যবহার করতে পারেন:

// config/common/config/sequences.js

'use strict';

module.exports = {
    executeMySyncQueries: {
        operations: [
            {
                service: 'danf:http.router',
                method: 'follow',
                // Process the operation on each item
                // of the following collection.
                collection: {
                    // Define the input collection.
                    input: [
                        'www.example.com/api_1.php',
                        'www.example.com/api_2.php',
                        'www.example.com/api_3.php'
                    ],
                    // Define the async method used.
                    // You can specify any collection method
                    // of the async lib.
                    // '--' is a shorcut for 'forEachOfSeries'
                    // which is an execution in series.
                    method: '--'
                },
                arguments: [
                    // Resolve reference '@@.@@' in the context
                    // of the input item.
                    '@@.@@',
                    'GET'
                ],
                // Set the responses in the property 'responses'
                // of the stream.
                scope: 'responses'
            }
        ]
    }
};

কটাক্ষপাত ওভারভিউ আরও তথ্য জন্য কাঠামোর।


1

আমি এখানে অবতরণ করেছি কারণ আমাকে রেট-সীমাবদ্ধ করার দরকার ছিল http.request (বিশ্লেষণী প্রতিবেদন তৈরির জন্য 10 মিলিয়ন ডলারের স্থিতিস্থাপক অনুসন্ধানের অনুসন্ধান)। নিম্নলিখিত কেবল আমার মেশিন দম বন্ধ।

for (item in set) {
    http.request(... + item + ...);
}

আমার ইউআরএলগুলি খুব সহজ তাই এটি মূল প্রশ্নের ক্ষেত্রে তুচ্ছভাবে প্রয়োগ নাও হতে পারে তবে আমি মনে করি এটি পাঠকদের জন্য এখানে সম্ভাব্য প্রযোজ্য এবং মূল্যবান উভয়ই যা এখানে আমার মত একই সমস্যা এবং যারা তুচ্ছ জাভাস্ক্রিপ্ট নো-লাইব্রেরি সমাধান চান।

আমার কাজ নির্ভরশীল আদেশ ছিল না এবং এটিকে বডিংয়ের জন্য আমার প্রথম পদ্ধতির এটি শাঁস স্ক্রিপ্টে মুড়ে ফেলা ছিল (কারণ আমি জাভাস্ক্রিপ্টে নতুন)। এটি কার্যকরী ছিল তবে সন্তোষজনক নয়। আমার জাভাস্ক্রিপ্ট রেজোলিউশনটি শেষের দিকে করছিল:

var stack=[];
stack.push('BOTTOM');

function get_top() {
  var top = stack.pop();
  if (top != 'BOTTOM')
    collect(top);
}

function collect(item) {
    http.request( ... + item + ...
    result.on('end', function() {
      ...
      get_top();
    });
    );
}

for (item in set) {
   stack.push(item);
}

get_top();

এটি সংগ্রহ এবং get_top এর মধ্যে পারস্পরিক পুনরাবৃত্তি বলে মনে হচ্ছে । আমি নই নিশ্চিত করুন যে এটি কার্যকর কারণ সিস্টেম অ্যাসিঙ্ক্রোনাস হয় এবং ফাংশন সংগ্রহ একটি কলব্যাক সঙ্গে সম্পন্ন হয়ে এ ঘটনার জন্য stashed হয়েছে। ( 'শেষ'

আমি মনে করি এটি মূল প্রশ্নে প্রয়োগ করা যথেষ্ট সাধারণ। যদি, আমার দৃশ্যের মতো, সিকোয়েন্স / সেটটি জানা যায়, সমস্ত ইউআরএল / কীগুলি এক ধাপে স্ট্যাকের উপরে ঠেলা যায়। যদি আপনি সেগুলি হিসাবে গণনা করা হয় তবে অন ​​('শেষ' ফাংশনটি get_hop এর ঠিক আগে ( পরবর্তী) ইউআরএল স্ট্যাকের উপরে চাপ দিতে পারে ) কিছু যদি না হয় তবে ফলাফলটি কম থাকে এবং আপনি যে এপিআইটি কল করছেন তখন রিফ্যাক্টর করা সহজ হতে পারে) পরিবর্তন।

আমি বুঝতে পারি এটি কার্যকরভাবে উপরের @ জেনারেনেরির সাধারণ পুনরাবৃত্ত সংস্করণের সমতুল্য (সুতরাং আমি এটিকে অগ্রাহ্য করেছি!)


0

সুপার অনুরোধ

এটি আর একটি সিঙ্ক্রোনাস মডিউল যা অনুরোধের ভিত্তিতে এবং প্রতিশ্রুতি ব্যবহার করে। ব্যবহার করা খুব সহজ, মোচা টেস্টগুলির সাথে ভাল কাজ করে।

npm install super-request

request("http://domain.com")
    .post("/login")
    .form({username: "username", password: "password"})
    .expect(200)
    .expect({loggedIn: true})
    .end() //this request is done 
    //now start a new one in the same session 
    .get("/some/protected/route")
    .expect(200, {hello: "world"})
    .end(function(err){
        if(err){
            throw err;
        }
    });

0

এই কোডটি প্রতিশ্রুতিগুলির বিন্যাস সিঙ্ক্রোনসিভ এবং ক্রমানুসারে কার্যকর করতে ব্যবহার করা যেতে পারে যার পরে আপনি .then()কলটিতে আপনার চূড়ান্ত কোডটি কার্যকর করতে পারেন ।

const allTasks = [() => promise1, () => promise2, () => promise3];

function executePromisesSync(tasks) {
  return tasks.reduce((task, nextTask) => task.then(nextTask), Promise.resolve());
}

executePromisesSync(allTasks).then(
  result => console.log(result),
  error => console.error(error)
);

0

আপনি (এবং আমি) কোনও (বাহ্যিক) লাইব্রেরির (আমাদের নিজস্ব ব্যতীত) অপেক্ষা, প্রতিশ্রুতি বা অন্তর্ভুক্তি ব্যবহার না করে আপনি (এবং আমি) যা চেয়েছিলেন তা হুবহু পেয়েছি।

এটি কীভাবে করবেন তা এখানে:

আমরা নোড.জেএস সাথে যেতে একটি সি ++ মডিউল তৈরি করতে যাচ্ছি, এবং সেই সি ++ মডিউল ফাংশন এইচটিটিপি অনুরোধ করবে এবং তথ্যটিকে স্ট্রিং হিসাবে ফিরিয়ে দেবে, এবং আপনি সরাসরি এটি করে ব্যবহার করতে পারেন:

var myData = newModule.get(url);

আপনি কি শুরু করার জন্য প্রস্তুত ?

পদক্ষেপ 1: আপনার কম্পিউটারে অন্য কোথাও একটি নতুন ফোল্ডার তৈরি করুন, আমরা কেবলমাত্র মডিউল.নোড ফাইল (সি ++ থেকে সংকলিত) তৈরি করতে এই ফোল্ডারটি ব্যবহার করছি, আপনি এটি পরে স্থানান্তর করতে পারেন।

নতুন ফোল্ডারে (আমি সংগঠন-নেসের জন্য আমার নতুন ফোল্ডার / এসসিআর-এ আমার রাখি):

npm init

তারপর

npm install node-gyp -g

এখন 2 টি নতুন ফাইল তৈরি করুন: 1, যাকে কিছু বলা হয় সিপিসিপি এবং এতে এই কোডটি রাখার জন্য (বা আপনি চাইলে এটি পরিবর্তন করুন):

#pragma comment(lib, "urlmon.lib")
#include <sstream>
#include <WTypes.h>  
#include <node.h>
#include <urlmon.h> 
#include <iostream>
using namespace std;
using namespace v8;

Local<Value> S(const char* inp, Isolate* is) {
    return String::NewFromUtf8(
        is,
        inp,
        NewStringType::kNormal
    ).ToLocalChecked();
}

Local<Value> N(double inp, Isolate* is) {
    return Number::New(
        is,
        inp
    );
}

const char* stdStr(Local<Value> str, Isolate* is) {
    String::Utf8Value val(is, str);
    return *val;
}

double num(Local<Value> inp) {
    return inp.As<Number>()->Value();
}

Local<Value> str(Local<Value> inp) {
    return inp.As<String>();
}

Local<Value> get(const char* url, Isolate* is) {
    IStream* stream;
    HRESULT res = URLOpenBlockingStream(0, url, &stream, 0, 0);

    char buffer[100];
    unsigned long bytesReadSoFar;
    stringstream ss;
    stream->Read(buffer, 100, &bytesReadSoFar);
    while(bytesReadSoFar > 0U) {
        ss.write(buffer, (long long) bytesReadSoFar);
        stream->Read(buffer, 100, &bytesReadSoFar);
    }
    stream->Release();
    const string tmp = ss.str();
    const char* cstr = tmp.c_str();
    return S(cstr, is);
}

void Hello(const FunctionCallbackInfo<Value>& arguments) {
    cout << "Yo there!!" << endl;

    Isolate* is = arguments.GetIsolate();
    Local<Context> ctx = is->GetCurrentContext();

    const char* url = stdStr(arguments[0], is);
    Local<Value> pg = get(url,is);

    Local<Object> obj = Object::New(is);
    obj->Set(ctx,
        S("result",is),
        pg
    );
    arguments.GetReturnValue().Set(
       obj
    );

}

void Init(Local<Object> exports) {
    NODE_SET_METHOD(exports, "get", Hello);
}

NODE_MODULE(cobypp, Init);

এখন একই ডিরেক্টরিতে একটি নতুন ফাইল তৈরি করুন এবং এতে এটি something.gyp(এমন কিছু) রাখুন:

{
   "targets": [
       {
           "target_name": "cobypp",
           "sources": [ "src/cobypp.cpp" ]
       }
   ]
}

এখন প্যাকেজ.জসন ফাইলে যোগ করুন: "gypfile": true,

এখন: কনসোলে, node-gyp rebuild

যদি এটি পুরো কমান্ডটি অতিক্রম করে এবং কোনও ত্রুটি না করে শেষে "ঠিক আছে" বলে, আপনি (প্রায়) ভাল, যদি না হয় তবে ভাল মন্তব্য করুন ..

তবে যদি এটি কাজ করে তবে বিল্ড / রিলিজ / cobypp.node (অথবা এটি আপনার জন্য যা কিছু বলবে) যান, আপনার মূল নোড.জেএস ফোল্ডারে কপি করুন, তারপরে নোড.জেজে:

var myCPP = require("./cobypp")
var myData = myCPP.get("http://google.com").result;
console.log(myData);

..

response.end(myData);//or whatever
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.