Node.js में सिंक्रोनस अनुरोध


99

अगर मुझे क्रमबद्ध क्रम में 3 http एपीआई को कॉल करने की आवश्यकता है, तो निम्न कोड का एक बेहतर विकल्प क्या होगा:

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) { 


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

सफाई के अलावा, मुझे नहीं लगता कि आप इससे बेहतर कर सकते हैं।
hvgotcodes

2
उन्हें क्रम में रहने की आवश्यकता क्यों है?
रेयानोस

11
@Raynos आपको api_1 से कुछ डेटा की आवश्यकता हो सकती है इससे पहले कि आप जानते हैं कि api_2 को क्या भेजा जाए
andyortlieb

9
यह ध्यान देने योग्य है कि फ़्यूचर्स बहुत ही पदावनत है, ब्लूबर्ड या क्यू जैसे एक नए पुस्तकालय का उपयोग करने पर विचार करें
बेंजामिन ग्रुएनबाउम

1
शीर्षक और प्रश्न एक-दूसरे का खंडन करते हैं। आप अपने प्रश्न में एक तुल्यकालिक अनुरोध का वर्णन नहीं कर रहे हैं, लेकिन अनुरोधों का एक क्रम है, जो आमतौर पर प्रत्येक अतुल्यकालिक रूप से होता है। बड़ा अंतर - एक तुल्यकालिक कॉल ब्लॉक, और अतुल्यकालिक कार्यों का एक क्रम ब्लॉक नहीं करता है (यूआई को ब्लॉक करें, सर्वर को अन्य अनुरोधों से निपटने से रोकें)। sync-requestपुस्तकालय का उल्लेख करने के नीचे एक उत्तर है , जो इस प्रश्न के शीर्षक का एक अच्छा उत्तर है, लेकिन इस प्रश्न का कोड क्या है इसका उत्तर नहीं है। प्रॉमिस के बारे में नीचे दिया गया उत्तर उसके लिए बेहतर उत्तर है। आपका क्या मतलब था?
जेक

जवाबों:


69

जैसे deferreds का उपयोग करना 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) { })
    ...
  })

कृपया IcedCoffeScript आज़माएं, जो नोडज के लिए प्रतीक्षा और अवहेलना प्रदान करता है।
थानीगैनाथन

क्या यह गैर अवरुद्ध है? मेरा मतलब है कि यह लाइन में अगले समारोह के लिए अवरुद्ध है, लेकिन यह अन्य async कार्यों के निष्पादन को अवरुद्ध नहीं करेगा, क्या यह होगा?
ओक्टाव

1
हां, आस्थगित विधियाँ गैर-अवरोधक / एसिंक्स हैं।
DVlsg

4
ES6 प्रॉमिस एपीआई को प्रभावी रूप से इसे बदलना चाहिए, यहां तक ​​कि "फ्यूचर्स" के लेखक के अनुसार
अलेक्जेंडर मिल्स

फ्यूचर्स बहुत पुराना और पदावनत है। इसके बजाय q देखें।
जिम आहो

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
हा। example.com वास्तव में इस तरह की चीज़ के लिए डिज़ाइन किया गया एक डोमेन है। वाह।
मेवप्लप

Async.series कोड काम नहीं करता है, कम से कम async v0.2.10 के रूप में। श्रृंखला () केवल दो तर्कों तक ले जाती है और पहले तर्क के तत्वों को फ़ंक्शन के रूप में निष्पादित करेगी, इसलिए async ऑब्जेक्ट्स को फ़ंक्शन के रूप में निष्पादित करने की कोशिश में एक त्रुटि फेंकता है।
ढक्कन

1
इस कोड के साथ forEachAsync ( 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');

3
बकवास, मैं सोच रहा था कि यह काम करेगा और यह नहीं है :(require(...).HttpClient is not a constructor
मोइस्कूल

30

सिंक-अनुरोध

अब तक मैंने जो सबसे आसान पाया है, उसका उपयोग किया है, सिंक-रिक्वेस्ट है और यह नोड और ब्राउज़र दोनों को सपोर्ट करता है!

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

यही कारण है कि, कोई पागल विन्यास, कोई जटिल कामेच्छा स्थापित नहीं करता है, हालांकि इसमें एक वाणिज्यिक गिरावट है। बस काम करता है। मैं यहाँ अन्य उदाहरणों की कोशिश कर चुका हूँ और जब काम करने के लिए बहुत अतिरिक्त सेटअप था तो स्टम्प्ड था या काम नहीं किया था!

टिप्पणियाँ:

उदाहरण जो सिंक-रिक्वेस्ट करता है का उपयोग करता है res.getBody(), जब आप उपयोग करते हैं तो अच्छा नहीं खेलते हैं , सभी को शरीर मिलता है एन्कोडिंग को स्वीकार करता है और प्रतिक्रिया डेटा को परिवर्तित करता है। res.body.toString(encoding)इसके बजाय बस करो ।


मैंने पाया कि सिंक-रिक्वेस्ट बहुत धीमी है .. मैंने एक और एक github.com/dhruvbird/http-sync का उपयोग करके समाप्त कर दिया है जो मेरे मामले में 10 गुना तेज है।
फिलिप स्पिरिडोनोव

मेरे पास इसके लिए कोई धीमा रन नहीं था। यह एक बच्चे की प्रक्रिया को जन्म देती है। आपका सिस्टम कितने cpus का उपयोग करता है और आप किस नोड के संस्करण का उपयोग कर रहे हैं? मुझे यह जानना अच्छा लगेगा कि मुझे स्विच करने की आवश्यकता है या नहीं।
जेमलोइ

मैं फ़िलिप से सहमत हूँ, यह धीमा है।
रेम्बो 7

एक ही बात मैंने फ्लिप से पूछा है, लेकिन कोई प्रतिक्रिया नहीं मिली है: आपका सिस्टम कितने cpus का उपयोग करता है और आप किस नोड के संस्करण का उपयोग कर रहे हैं?
जेमलोइ

यह सीपीयू की एक गंभीर मात्रा का उपयोग करता है, उत्पादन के उपयोग के लिए अनुशंसित नहीं है।
मोइस्कूल

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 );

संपादित करें: अनुरोध / async संस्करण

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
});

यह वह विधि है जिसे मैंने नियोजित किया है क्योंकि मेरे पास बनाने के लिए अनुरोधों की एक चर सूची है (600 आइटम और बढ़ती)। उस ने कहा, आपके कोड के साथ एक समस्या है: एपीआई आउटपुट चंक आकार से अधिक होने पर प्रति अनुरोध 'डेटा' घटना कई बार उत्सर्जित होगी। आप डेटा को "बफर" करना चाहते हैं जैसे: var body = ''; res.on ('डेटा', फंक्शन (डेटा) {बॉडी + = डेटा;})। ('एंड', फंक्शन () {कॉलबैक (बॉडी) पर; यदि (APIs.length) callAPIs (होस्ट, APIs);} );
अंकित अग्रवाल

अपडेट किया गया। मैं सिर्फ यह दिखाना चाहता था कि कैसे समस्या को पुनरावृत्ति के माध्यम से सरल / अधिक लचीला बनाया जा सकता है। व्यक्तिगत रूप से मैं हमेशा इस तरह के लिए अनुरोध मॉड्यूल का उपयोग करता हूं क्योंकि यह आपको आसानी से कई कॉलबैक को छोड़ देता है।
'18:59 पर सामान्यजन

@generalhenry, अगर मैं अनुरोध मॉड्यूल का उपयोग करना चाहता हूं तो मैं यह कैसे करूंगा? क्या आप एक कोड स्निपेट प्रदान कर सकते हैं जो अनुरोध का उपयोग करके उपरोक्त प्राप्त करता है?
स्कूटी

मैंने एक अनुरोध संस्करण और एक अनुरोध / async संस्करण जोड़ा।
सामान्य कृति 25'13

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 हमेशा सिंक होता है।
एरिक

1
नहीं, आप स्पष्ट रूप से कॉलबैक की आपूर्ति कर सकते हैं और यदि आप चाहें तो इसे अतुल्यकालिक संस्करण के रूप में उपयोग कर सकते हैं।
एलेक्स क्राफ्ट

1
उदाहरण http अनुरोधों के लिए था, लेकिन सिस्टम संचार फ़ाइल नहीं।
सेठ

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;

ठीक है, यह सुंदर नहीं है। यह अनुक्रमिक कॉल करने का एक और तरीका है। यह दुर्भाग्यपूर्ण है कि NodeJS सबसे बुनियादी तुल्यकालिक कॉल प्रदान नहीं करता है। लेकिन मैं समझता हूं कि लालच क्या अतुल्यकालिकता है।


4

अनुक्रम का उपयोग करें।

sudo npm सं थापक सं थापन

या

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!

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)
    }
)

3

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कीवर्ड का उपयोग करके )


2

बहुत सारे नियंत्रण प्रवाह पुस्तकालय हैं - मुझे कॉनसेक पसंद है ... (क्योंकि मैंने इसे लिखा था।) इसके अलावा, on('data')कई बार आग लगा सकते हैं, इसलिए रेस्टर की तरह REST रैपर लाइब्रेरी का उपयोग करें ।

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/fterence/tree/9daf0000289954b85c0925119821752fbf3535e

इसके बाद आप इसे कैसे काम कर सकते हैं npm install sequence:

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

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

1

यहाँ अनुक्रमणिका के बजाय सरणी में क्रमिक रूप से @ andy-shin का मेरा संस्करण है:

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

1

...चार साल बाद...

यहाँ Danf के साथ एक मूल समाधान है (आपको इस तरह की चीजों के लिए किसी भी कोड की आवश्यकता नहीं है, केवल कुछ विन्यास):

// 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'
            }
        ]
    }
};

अधिक informations के लिए रूपरेखा के अवलोकन पर एक नज़र डालें ।


1

मैं यहां इसलिए उतरा क्योंकि मुझे एक विश्लेषणात्मक रिपोर्ट बनाने के लिए लोचदार खोज के लिए http.request (~ 10k एकत्रीकरण प्रश्नों की दर-सीमा) की आवश्यकता थी। निम्नलिखित ने मेरी मशीन को चोक कर दिया।

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

मेरे URL बहुत सरल हैं, इसलिए यह मूल प्रश्न पर तुच्छ रूप से लागू नहीं हो सकता है, लेकिन मुझे लगता है कि यह उन पाठकों के लिए यहां संभावित रूप से लागू और लिखने योग्य है, जो मेरे जैसे ही मुद्दों के साथ यहां आते हैं और जो एक तुच्छ जावास्क्रिप्ट नो-लाइब्रेरी समाधान चाहते हैं।

मेरा काम आश्रित नहीं था और इसे चकमा देने के लिए मेरा पहला तरीका यह था कि इसे खोल स्क्रिप्ट में लपेटकर इसे चंक कर दिया जाए (क्योंकि मैं जावास्क्रिप्ट में नया हूं)। यह क्रियात्मक था लेकिन संतोषजनक नहीं था। अंत में मेरा जावास्क्रिप्ट संकल्प निम्नलिखित करना था:

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 के बीच पारस्परिक पुनरावृत्ति जैसा दिखता है । मुझे यकीन नहीं है कि यह प्रभाव में है क्योंकि सिस्टम अतुल्यकालिक है और इस घटना के लिए समारोह में कॉलबैक स्टैक्ड के साथ फ़ंक्शन एकत्रित होता है। ('अंत')

मुझे लगता है कि मूल प्रश्न पर लागू करना काफी सामान्य है। यदि, मेरे परिदृश्य की तरह, अनुक्रम / सेट ज्ञात है, तो सभी URL / कुंजियों को एक चरण में स्टैक पर धकेल दिया जा सकता है। यदि आप जाते समय उनकी गणना करते हैं, तो (। 'अंत' फ़ंक्शन .top () के ठीक पहले स्टैक पर अगले url को धकेल सकता है । यदि कुछ भी हो, तो परिणाम में कम घोंसला होता है और एपीआई को कॉल करने पर रिफ्लेक्टर करना आसान हो सकता है। परिवर्तन।

मुझे लगता है कि यह प्रभावी रूप से ऊपर @ सामान्यजन के सरल पुनरावर्ती संस्करण के बराबर है (इसलिए मैंने इसे उखाड़ा है!)।


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

मुझे वास्तव में वही मिला, जो आप (और मेरे) चाहते थे, बिना किसी प्रतीक्षा के, प्रोमिस या किसी भी (बाहरी) पुस्तकालय (हमारे अपने को छोड़कर) के उपयोग के बिना।

यह कैसे करना है:

हम नोड C.js के साथ जाने के लिए C ++ मॉड्यूल बनाने जा रहे हैं, और C ++ मॉड्यूल फ़ंक्शन HTTP अनुरोध करेगा और डेटा को एक स्ट्रिंग के रूप में वापस करेगा, और आप इसे सीधे करके उपयोग कर सकते हैं:

var myData = newModule.get(url);

क्या आप आरंभ करने के लिए तैयार हैं ?

चरण 1: अपने कंप्यूटर पर कहीं और एक नया फ़ोल्डर बनाएं, हम केवल इस फ़ोल्डर का उपयोग मॉड्यूल.नोड फ़ाइल (C ++ से संकलित) बनाने के लिए कर रहे हैं, आप इसे बाद में स्थानांतरित कर सकते हैं।

नए फ़ोल्डर में (मैंने ऑर्गन-नेस के लिए mynewFolder / src में अपना नाम डाला):

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" ]
       }
   ]
}

अब package.json फ़ाइल में, जोड़ें: "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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.