নোড.জেএস বা জাভাস্ক্রিপ্টে সিঙ্ক ফাংশনে অ্যাসিঙ্ক ফাংশন কলগুলি কীভাবে মোড়ানো যায়?


122

ধরুন আপনি কোনও লাইব্রেরি বজায় রেখেছেন যা কোনও ফাংশন প্রকাশ করে getData। আপনার ব্যবহারকারীরা প্রকৃত ডেটা পেতে এটি কল করে:
var output = getData();
হুডের নীচে কোনও ফাইলে ডেটা সংরক্ষণ করা হয় যাতে আপনি getDataবিল্ট-ইন নোড.জেস ব্যবহার করে প্রয়োগ করেছিলেন fs.readFileSync। এটি উভয়ই সুস্পষ্ট getDataএবং fs.readFileSyncসিঙ্ক ফাংশন। একদিন আপনাকে অন্তর্নিহিত ডেটা উত্সকে মঙ্গোডিবি এর মতো একটি রেপোতে স্যুইচ করতে বলা হয়েছিল যা কেবলমাত্র তাত্পর্যপূর্ণভাবে অ্যাক্সেস করা যায়। আপনাকে আপনার ব্যবহারকারীদের বিস্ফোরিত হওয়া এড়াতে বলা হয়েছিল, getDataকেবল প্রতিশ্রুতি ফিরে আসতে বা একটি কলব্যাক প্যারামিটার দাবি করার জন্য এপিআই পরিবর্তন করা যাবে না। আপনি উভয় প্রয়োজনীয়তা কিভাবে পূরণ করবেন?

কলব্যাক / প্রতিশ্রুতি ব্যবহার করে অ্যাসিঙ্ক্রোনাস ফাংশন হ'ল জাভাস্রিপ্ট এবং নোড.জেএস এর ডিএনএ is যে কোনও অ-তুচ্ছ জেএস অ্যাপ্লিকেশন সম্ভবত এই কোডিং শৈলীর সাথে জড়িত। তবে এই অনুশীলনটি সহজেই ডুমের ডাকা পিরামিড তথাকথিত কলব্যাকের দিকে নিয়ে যেতে পারে। আরও খারাপ, কল চেইনের কোনও কলারের কোনও কোড যদি অ্যাসিঙ্ক ফাংশনের ফলাফলের উপর নির্ভর করে তবে সেই কোডগুলিকে কলব্যাক ফাংশনেও আবৃত করতে হবে, কলারের উপর কোডিং শৈলীর সীমাবদ্ধতা চাপিয়ে দেওয়া উচিত। সময়ে সময়ে আমি বিশাল বৈশ্বিক পুনঃ-ফ্যাক্টরিং এড়ানোর জন্য একটি সিঙ্ক ফাংশনে একটি অ্যাসিঙ্ক ফাংশন (প্রায়শই একটি তৃতীয় পক্ষের লাইব্রেরিতে সরবরাহ করা হয়) সজ্জিত করার প্রয়োজনীয়তাটি পাই। এই বিষয়ে কোনও সমাধান অনুসন্ধান করা সাধারণত নোড ফাইবার্সের সাথে শেষ হয়বা এটি থেকে প্রাপ্ত এনপিএম প্যাকেজগুলি। তবে ফাইবাররা কেবল আমার যে সমস্যার মুখোমুখি হচ্ছে তা সমাধান করতে পারে না। এমনকি ফাইবার্সের লেখক যে উদাহরণ দিয়েছেন তার ঘাটতি তুলে ধরে:

...
Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

আসল আউটপুট:

wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)

যদি ফাংশন ফাইবার সত্যই অ্যাসিঙ্ক ফাংশন স্লিপকে সিঙ্ক করে দেয়, আউটপুটটি হওয়া উচিত:

wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
back in main

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


2
অ্যাসিঙ্ক ফাংশনগুলি কখনই নোডে সিঙ্ক্রোনাস করা যায় না এবং এমনকি যদি তারা করতে পারে তবে আপনার করা উচিত নয়। সমস্যাটি এমন যে fs মডিউলে আপনি ফাইল সিস্টেমে সিঙ্ক্রোনাস এবং অ্যাসিনক্রোনাস অ্যাক্সেসের জন্য সম্পূর্ণ পৃথক ফাংশন দেখতে পাবেন। আপনি যেটা করতে পারেন সেরা তা হল প্রতিশ্রুতি বা করোটিনগুলির সাথে ইসিনের উপস্থিতির মুখোশ ( কলব্যাক পিরামিড পরিচালনার জন্য, একটি ফাংশন কলে সংজ্ঞায়নের পরিবর্তে তাদের নাম দিন এবং অ্যাসিঙ্ক লাইব্রেরির মতো কিছু ব্যবহার করুন।
qubyte

8
ডান্ডাভিসের জন্য, অ্যাসিঙ্ক কল চেইনে বাস্তবায়ন বিশদটি বুদবুদ করে, কখনও কখনও গ্লোবাল রিফ্যাক্টরিংকে বাধ্য করে। এটি এমন একটি জটিল অ্যাপ্লিকেশনের জন্য ক্ষতিকারক এবং এমনকি বিপর্যয়কর যেখানে মডুলারাইজেশন এবং সংযোজন গুরুত্বপূর্ণ।
সংক্ষিপ্তকরণ

4
"ডাবের কলব্যাক পিরামিড" কেবল সমস্যার প্রতিনিধিত্ব করে। প্রতিশ্রুতি এটি আড়াল বা ছদ্মবেশ ধারণ করতে পারে তবে সত্য চ্যালেঞ্জ মোকাবেলা করতে পারে না: যদি কোনও অ্যাসিঙ্ক ফাংশন কলকারী অ্যাসিঙ্ক ফাংশনের ফলাফলের উপর নির্ভর করে তবে এটি কলব্যাক ব্যবহার করতে হবে, এবং তার কলার ইত্যাদি This এটি প্রতিবন্ধকতা আরোপ করার একটি শাস্ত্রীয় উদাহরণ is কলকারী কেবল বাস্তবায়নের বিশদের কারণে।
সংক্ষিপ্তকরণ

1
@ অ্যাবআর: ডি্যাসিন্যাস মডিউলটির জন্য ধন্যবাদ, আপনার সমস্যার বর্ণনাটি ঠিক আমি যা খুঁজছিলাম তা হ'ল এবং কার্যকর কোন সমাধান খুঁজে পেল না। আমি জেনারেটর এবং পুনরাবৃত্তকারীগুলির সাথে চারপাশে গোলযোগ করেছি, তবে আপনার মত একই সিদ্ধান্তে এসেছি।
কেভিন ঝাংগেইনি

2
এটি লক্ষণীয় যে অ্যাসিঙ্ক ফাংশনটিকে সিঙ্ক হওয়ার জন্য জোর করা প্রায় কখনও ভাল ধারণা নয় । আপনার প্রায় সবসময়ই আরও ভাল সমাধান থাকে যা ফাংশনটির অ্যাসিঙ্ক-নেসটি অক্ষত রাখে, তবুও একই প্রভাব অর্জন করে (যেমন সিকোয়েন্সিং, ভেরিয়েবল সেটিং ইত্যাদি)।
মাদারার ঘোস্ট

উত্তর:


104

ডায়্যাসিঙ্ক জাভাস্ক্রিপ্ট স্তরে নোড.জেএস ইভেন্ট লুপকে কল করে একটি ব্লকিং মেকানিজম দ্বারা কার্যকর করা, অ্যাসিঙ্ক ফাংশনটিকে সিঙ্কে পরিণত করে। ফলস্বরূপ, ডায়াসিঙ্ক কেবল পরবর্তী কোডটি পুরো থ্রেডটি ব্লক না করে চালানো থেকে বিরত রাখে, না ব্যস্ততার অপেক্ষা করতে পারে। এই মডিউলটির সাথে, এখানে jsFizz চ্যালেঞ্জের উত্তর:

function AnticipatedSyncFunction(){
  var ret;
  setTimeout(function(){
      ret = "hello";
  },3000);
  while(ret === undefined) {
    require('deasync').runLoopOnce();
  }
  return ret;    
}


var output = AnticipatedSyncFunction();
//expected: output=hello (after waiting for 3 sec)
console.log("output="+output);
//actual: output=hello (after waiting for 3 sec)

(অস্বীকৃতি: আমি এর সহ-লেখক deasyncThe এই প্রশ্নটি পোস্ট করার পরে মডিউলটি তৈরি করা হয়েছিল এবং কার্যকর কোনও প্রস্তাব পাওয়া যায়নি))


এর সাথে ভাগ্য কি আর কারও ছিল? আমি এটি কাজ করতে পারি না।
নিউম্যান

3
আমি এটি সঠিকভাবে কাজ করতে পারি না। আপনি যদি চান যে এটি আরও ব্যবহৃত হয় তবে এই মডিউলটির জন্য আপনার ডকুমেন্টেশনগুলি উন্নত করা উচিত। আমি সন্দেহ করি যে লেখকরা মডিউলটি ব্যবহারের জন্য র্যামফিকেশনগুলি ঠিক কী তা জানেন এবং যদি তারা করেন তবে তারা অবশ্যই এগুলি নথিভুক্ত করবেন না।
আলেকজান্ডার মিলস

5
এখনও অবধি গিথুব ইস্যু ট্র্যাকারে নথিভুক্ত একটি নিশ্চিত সমস্যা রয়েছে। নোড v0.12 এ সমস্যাটি স্থির করা হয়েছে। আমি জানি বাকিটি নিছক ভিত্তিহীন জল্পনা যা ডকুমেন্টের পক্ষে মূল্যহীন নয়। যদি আপনি বিশ্বাস করেন যে আপনার সমস্যাটি ডিয়েসেনেকের কারণে হয়েছে তবে একটি স্ব-অন্তর্ভুক্ত, সদৃশ দৃশ্য পোস্ট করুন এবং আমি এটি সন্ধান করব।
আব্বার

আমি এটি ব্যবহার করার চেষ্টা করেছি এবং আমার স্ক্রিপ্টে কিছু উন্নতি পেয়েছি তবে তবুও তারিখটি নিয়ে আমার ভাগ্য হয়নি। আমি কোডটি অনুসরণ হিসাবে সংশোধন করেছি: function AnticipatedSyncFunction(){ var ret; setTimeout(function(){ var startdate = new Date() //console.log(startdate) ret = "hello" + startdate; },3000); while(ret === undefined) { require('deasync').runLoopOnce(); } return ret; } var output = AnticipatedSyncFunction(); var startdate = new Date() console.log(startdate) console.log("output="+output); এবং আমি তারিখের আউটপুটে 3 সেকেন্ডের আলাদা দেখতে আশা করি!
অ্যালেক্স

@ এববিআর এটি নোড নির্ভরতা ছাড়াই ব্রাউজ করা এবং ব্যবহার করা যেতে পারে>
গান্ধী

5

একটি এনপিএম সিঙ্ক মডিউলও রয়েছে। যা ক্যোরি কার্যকর করার প্রক্রিয়াটিকে সিঙ্ক্রোনাইজ করার জন্য ব্যবহৃত হয়।

আপনি যখন সমান্তরাল প্রশ্নগুলি সিঙ্ক্রোনাস উপায়ে চালাতে চান তখন নোড এটি করতে সীমাবদ্ধ কারণ এটি কখনই প্রতিক্রিয়াটির জন্য অপেক্ষা করে না। এবং সিঙ্ক মডিউলটি সেই ধরণের সমাধানের জন্য অনেক উপযুক্ত।

কোডের উদাহরণ

/*require sync module*/
var Sync = require('sync');
    app.get('/',function(req,res,next){
      story.find().exec(function(err,data){
        var sync_function_data = find_user.sync(null, {name: "sanjeev"});
          res.send({story:data,user:sync_function_data});
        });
    });


    /*****sync function defined here *******/
    function find_user(req_json, callback) {
        process.nextTick(function () {

            users.find(req_json,function (err,data)
            {
                if (!err) {
                    callback(null, data);
                } else {
                    callback(null, err);
                }
            });
        });
    }

রেফারেন্স লিঙ্ক: https://www.npmjs.com/package/sync


4

যদি ফাংশন ফাইবার সত্যই অ্যাসিঙ্ক ফাংশন স্লিপকে সিঙ্কে পরিণত করে

হ্যাঁ. ফাইবারের অভ্যন্তরে, ফাংশন লগিংয়ের আগে অপেক্ষা করে ok। ফাইবারগুলি অ্যাসিঙ্ক ফাংশনগুলিকে সিঙ্ক্রোনাস করে না, তবে সিঙ্ক্রোনাস-লুকিং কোড লিখতে দেয় যা অ্যাসিঙ্ক ফাংশন ব্যবহার করে এবং তারপরে একটি এর অভ্যন্তরে অ্যাসিঙ্ক্রোনালি চালিত হবে Fiber

সময়ে সময়ে আমি বিশাল বৈশ্বিক পুনঃ-ফ্যাক্টরিং এড়ানোর জন্য একটি সিঙ্ক ফাংশনে একটি অ্যাসিঙ্ক ফাংশনটি সজ্জিত করার প্রয়োজনীয়তাটি খুঁজে পাই।

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

আমার উদ্দেশ্য হ'ল কলকারীর উপর প্রভাব হ্রাস করা যখন ডেটা অর্জনের পদ্ধতি সিঙ্ক থেকে অ্যাসিঙ্কে পরিবর্তিত হয়

প্রতিশ্রুতি এবং তন্তু উভয়ই এটি করতে পারে।


1
এটি নোড.জেএস এর সাথে আপনি করতে পারেন নিখরচায় সবচেয়ে খারাপ জিনিস: "সিঙ্ক্রোনাস-লুকিং কোড যা অ্যাসিঙ্ক ফাংশন ব্যবহার করে এবং তারপরে অ্যাসিঙ্ক্রোনালি চালিত হবে।" যদি আপনার এপিআই এটি করে, আপনি জীবনকে নষ্ট করবেন। যদি এটি অ্যাসিঙ্ক্রোনাস হয় তবে এটির জন্য একটি কলব্যাক প্রয়োজন এবং কোনও কলব্যাক সরবরাহ না করা থাকলে একটি ত্রুটি নিক্ষেপ করা উচিত। আপনার লক্ষ্য মানুষকে ঠকানো না হলে এপিআই তৈরির সর্বোত্তম উপায় the
আলেকজান্ডার মিলস

@ অ্যালেক্সমিলস: হ্যাঁ, এটি সত্যই ভয়ঙ্কর হবে। তবে ভাগ্যক্রমে এটি কোনও এপিআই করতে পারে না। একটি অ্যাসিঙ্ক্রোনাস এপিআইকে সর্বদা কলব্যাক গ্রহণ করা / প্রতিশ্রুতি ফিরিয়ে নেওয়া / ফাইবারের অভ্যন্তরে চালিত হওয়া আশা করা দরকার - এটি ছাড়া কার্যকর হয় না। আফাক, ফাইবারগুলি বেশিরভাগই ক্লিক'নড্ডি স্ক্রিপ্টগুলিতে ব্যবহৃত হত যা অবরুদ্ধ ছিল এবং এতে কোনও সমঝোতা নেই, তবে অ্যাসিঙ্ক এপিআই ব্যবহার করতে চান; ঠিক নোডের মতোই কখনও কখনও এমন ঘটনা ঘটে থাকে আপনি যখন সিঙ্ক্রোনাস fsপদ্ধতি ব্যবহার করেন ।
বার্গি

2
আমি সাধারণত নোড পছন্দ করি। বিশেষত যদি আমি বিশুদ্ধ জেসের পরিবর্তে টাইপস্ক্রিপ্ট ব্যবহার করতে পারি। তবে এই পুরো অ্যাসিঙ্ক অযৌক্তিকরতা যা আপনি যা কিছু করেন এবং আক্ষরিক অর্থে কল চেইনের প্রতিটি ক্রিয়াকে সংক্রামিত করার সাথে সাথে আপনি একটি একক অ্যাসিঙ্ক কল করার সিদ্ধান্ত নেওয়ার সাথে সাথে আমি সত্যিই ঘৃণা করি। অ্যাসিঙ্ক এপিআই একটি সংক্রামক রোগের মতো, একটি কল আপনার সম্পূর্ণ কোড বেসকে সংক্রামিত করে যা আপনাকে আপনার সমস্ত কোড পুনরায় লিখতে বাধ্য করে। আমি সত্যিই বুঝতে পারি না যে কেউ কীভাবে সম্ভবত যুক্তি করতে পারে এটি একটি ভাল জিনিস।
ক্রিস

@ ক্রিস নোড আইও কার্যগুলির জন্য একটি অ্যাসিনক্রোনাস মডেল ব্যবহার করেছেন কারণ এটি দ্রুত এবং সহজ simple আপনি একসাথে অনেকগুলি জিনিসও করতে পারেন, তবে আপনি একইসাথে কিছু করতে না পারার কারণে ব্লক করা ধীর - আপনি যদি থ্রেডের জন্য না যান, যা সবকিছুকে জটিল করে তোলে।
বার্গি

@ বেরগি আমি ইশতেহারটি পড়েছি তাই আমি যুক্তিগুলি জানতে পারি। তবে আপনার বিদ্যমান কোডটি অ্যাসিঙ্কে পরিবর্তন করা সেই মুহুর্তে আপনি যখন প্রথম এপিআই কলটি কল করেন যা কোনও সিঙ্কের সমতুল্য নয় তেমন সহজ নয় । সমস্ত কিছু বিরতি এবং কোডের প্রতিটি এক লাইন যাচাই করতে হবে। আপনার কোডটি তুচ্ছ না হলে আমি গ্যারান্টি দিচ্ছি ... পুরো জিনিসটিকে async idiom এ রূপান্তর করার পরে রূপান্তর করতে এবং এটি আবার কাজ করতে কিছুক্ষণ সময় লাগবে।
ক্রিস

2

আপনি প্রতিশ্রুতি ব্যবহার করতে হবে:

const asyncOperation = () => {
    return new Promise((resolve, reject) => {
        setTimeout(()=>{resolve("hi")}, 3000)
    })
}

const asyncFunction = async () => {
    return await asyncOperation();
}

const topDog = () => {
    asyncFunction().then((res) => {
        console.log(res);
    });
}

আমি তীর ফাংশন সংজ্ঞা আরও পছন্দ করি। তবে "() => {... form" ফর্মের যে কোনও স্ট্রিংকে "ফাংশন () {...}" হিসাবেও লেখা যেতে পারে

সুতরাং টপডগ একটি অ্যাসিঙ্ক ফাংশন কল করার পরেও অ্যাসিঙ্ক নয়।

এখানে চিত্র বর্ণনা লিখুন

সম্পাদনা: আমি বুঝতে পারি যে আপনার একটি সিঙ্ক ফাংশনটির মধ্যে একটি অ্যাসিঙ্ক ফাংশনটি একটি নিয়ামকের অভ্যন্তরে আবৃত করা দরকার। এই পরিস্থিতিতে, একটি পার্টি কৌশল এখানে:

const getDemSweetDataz = (req, res) => {
    (async () => {
        try{
            res.status(200).json(
                await asyncOperation()
            );
        }
        catch(e){
            res.status(500).json(serviceResponse); //or whatever
        }
    })() //So we defined and immediately called this async function.
}

কলব্যাকগুলির সাহায্যে এটি ব্যবহার করে, আপনি এমন একটি মোড়ানো করতে পারেন যা প্রতিশ্রুতি ব্যবহার করে না:

const asyncOperation = () => {
    return new Promise((resolve, reject) => {
        setTimeout(()=>{resolve("hi")}, 3000)
    })
}

const asyncFunction = async (callback) => {
    let res = await asyncOperation();
    callback(res);
}

const topDog = () => {
    let callback = (res) => {
        console.log(res);
    };

    (async () => {
        await asyncFunction(callback)
    })()
}

ইভেন্টটমিটারে এই কৌশলটি প্রয়োগ করে আপনি একই ফলাফল পেতে পারেন। ইভেন্ট কলমিটারের শ্রোতার সংজ্ঞা দিন যেখানে আমি কলব্যাক সংজ্ঞায়িত করেছি, এবং ইভেন্টটি যেখানে আমি কলব্যাক বলেছিলাম তা নির্গত করে।


1

নোড-ফাইবার ব্যবহার করে সমাধান করা যায় না এমন দৃশ্য আমি খুঁজে পাচ্ছি না। আপনি নোড-ফাইবার ব্যবহার করে যে উদাহরণ সরবরাহ করেছেন তা প্রত্যাশার সাথে আচরণ করে। কীটি হ'ল ফাইবারের মধ্যে সমস্ত প্রাসঙ্গিক কোড চালানো, যাতে আপনাকে এলোমেলো অবস্থানগুলিতে একটি নতুন ফাইবার শুরু করতে হবে না।

একটি উদাহরণ দেখতে দিন: বলুন আপনি কিছু কাঠামো ব্যবহার করেন যা এটি আপনার অ্যাপ্লিকেশনের এন্ট্রি পয়েন্ট (আপনি এই কাঠামোটি সংশোধন করতে পারবেন না)। এই কাঠামোটি নোডেজ মডিউলগুলি প্লাগইন হিসাবে লোড করে এবং প্লাগইনগুলিতে কিছু পদ্ধতি কল করে। আসুন বলুন যে এই কাঠামোটি কেবলমাত্র সিনক্রোনাস ফাংশন গ্রহণ করে এবং নিজে থেকে ফাইবার ব্যবহার করে না।

একটি লাইব্রেরি রয়েছে যা আপনি আপনার প্লাগইনগুলির একটিতে ব্যবহার করতে চান, তবে এই লাইব্রেরিটি অ্যাসিঙ্ক, এবং আপনি এটি কোনও পরিবর্তন করতে চান না।

যখন কোনও ফাইবার চালু না থাকে তখন মূল থ্রেড পাওয়া যায় না তবে আপনি তন্তু ব্যবহার করে প্লাগিন তৈরি করতে পারেন! কেবল একটি মোড়কের এন্ট্রি তৈরি করুন যা একটি ফাইবারের ভিতরে পুরো কাঠামো শুরু করে, যাতে আপনি প্লাগইনগুলি থেকে সম্পাদন করতে পারেন।

ডাউনসাইড: যদি ফ্রেমওয়ার্কটি অভ্যন্তরীণভাবে ব্যবহার করে setTimeoutবা ব্যবহার করে Promise, তবে এটি ফাইবারের প্রসঙ্গে পালিয়ে যাবে will এই উপহাস দ্বারা প্রায় কাজ করা যেতে পারে setTimeout, Promise.thenএবং সমস্ত ইভেন্ট হ্যান্ডলার।

কোনও Promiseসমাধান না হওয়া পর্যন্ত আপনি এভাবেই একটি ফাইবার উত্পাদন করতে পারবেন । এই কোডটি একটি অ্যাসিঙ্ক (ফেরত দেওয়ার প্রতিশ্রুতি) ফাংশন নেয় এবং যখন প্রতিশ্রুতিটি সমাধান হয় তখন ফাইবারটি পুনরায় শুরু করে:

ফ্রেমওয়ার্ক-entry.js

console.log(require("./my-plugin").run());

ASYNC-lib.js

exports.getValueAsync = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("Async Value");
    }, 100);
  });
};

আমার-plugin.js

const Fiber = require("fibers");

function fiberWaitFor(promiseOrValue) {
  var fiber = Fiber.current, error, value;
  Promise.resolve(promiseOrValue).then(v => {
    error = false;
    value = v;
    fiber.run();
  }, e => {
    error = true;
    value = e;
    fiber.run();
  });
  Fiber.yield();
  if (error) {
    throw value;
  } else {
    return value;
  }
}

const asyncLib = require("./async-lib");

exports.run = () => {
  return fiberWaitFor(asyncLib.getValueAsync());
};

আমার-entry.js

require("fibers")(() => {
  require("./framework-entry");
}).run();

যখন আপনি চালাতে node framework-entry.jsএটি একটি ত্রুটির নিক্ষেপ করা হবে: Error: yield() called with no fiber running। আপনি যদি চালান node my-entry.jsএটি প্রত্যাশার মতো কাজ করে।


0

নোড.জেএস কোড সিঙ্ক তৈরি করা ডাটাবেসের মতো কয়েকটি ক্ষেত্রে প্রয়োজনীয়। তবে নোড.জেএসের আসল সুবিধাটি অ্যাসিঙ্ক কোডের মধ্যে রয়েছে। যেহেতু এটি একক থ্রেড অ-ব্লক করে।

আমরা গুরুত্বপূর্ণ কার্যকারিতা ফাইবার () অপেক্ষা () এবং ডিফার () ব্যবহার করে আমরা অপেক্ষা () ব্যবহার করে সমস্ত পদ্ধতি কল করি call তারপরে ডিফার () দিয়ে কলব্যাক ফাংশনগুলি প্রতিস্থাপন করুন।

সাধারণ অ্যাসিঙ্ক কোড.এটি কলব্যাক ফাংশন ব্যবহার করে।

function add (var a, var b, function(err,res){
       console.log(res);
});

 function sub (var res2, var b, function(err,res1){
           console.log(res);
    });

 function div (var res2, var b, function(err,res3){
           console.log(res3);
    });

উপরের কোডটি ফাইবার () ব্যবহার করে অপেক্ষা করুন () এবং স্থগিত করুন ()

fiber(function(){
     var obj1 = await(function add(var a, var b,defer()));
     var obj2 = await(function sub(var obj1, var b, defer()));
     var obj3 = await(function sub(var obj2, var b, defer()));

});

আমি আশা করি এটি সাহায্য করবে ধন্যবাদ


0

আজকাল এই জেনারেটর প্যাটার্নটি অনেক পরিস্থিতিতে সমাধান হতে পারে।

অ্যাসিঙ্ক রিডলাইন.কোশন ফাংশনটি ব্যবহার করে নোডজেজে সিক্যুয়াল কনসোলের একটি উদাহরণ দেওয়া হয়েছে:

var main = (function* () {

  // just import and initialize 'readline' in nodejs
  var r = require('readline')
  var rl = r.createInterface({input: process.stdin, output: process.stdout })

  // magic here, the callback is the iterator.next
  var answerA = yield rl.question('do you want this? ', r=>main.next(r))    

  // and again, in a sync fashion
  var answerB = yield rl.question('are you sure? ', r=>main.next(r))        

  // readline boilerplate
  rl.close()

  console.log(answerA, answerB)

})()  // <-- executed: iterator created from generator
main.next()     // kick off the iterator, 
                // runs until the first 'yield', including rightmost code
                // and waits until another main.next() happens

-1

কলটির চারপাশে কী ঘটে যা ফাইবার তৈরি করে তা নয় বরং ফাইবারের অভ্যন্তরে কী ঘটে সেদিকে লক্ষ্য করা উচিত নয়। একবার আপনি ফাইবারের ভিতরে গেলে আপনি সিঙ্ক স্টাইলে প্রোগ্রাম করতে পারেন। উদাহরণ স্বরূপ:

ফাংশন এফ 1 () {
    কনসোল.লগ ('অপেক্ষা ...' + নতুন তারিখ);
    ঘুম (1000);
    কনসোল.লগ ('ঠিক আছে ...' + নতুন তারিখ);   
}

ফাংশন f2 () {
    F1 ();
    F1 ();
}

ফাইবার (ফাংশন () {
    F2 ();
।}) চালানো ();

ফাইবার ইনসাইড আপনাকে কল f1, f2এবং sleepযেন তারা সিঙ্ক ছিলেন।

একটি সাধারণ ওয়েব অ্যাপ্লিকেশনটিতে, আপনি আপনার এইচটিটিপি অনুরোধ প্রেরণকারীতে ফাইবার তৈরি করবেন। একবার আপনি হয়ে গেলে আপনি আপনার সমস্ত অনুরোধ হ্যান্ডলিং লজিকে সিঙ্ক শৈলীতে লিখতে পারেন, এমনকি যদি এটি অ্যাসিঙ্ক ফাংশন (fs, ডাটাবেস, ইত্যাদি) কল করে।


ধন্যবাদ ব্রুনো তবে আমার যদি বুটস্ট্র্যাপ কোডে সিঙ্ক শৈলীর প্রয়োজন হয় যা সার্ভারের সাথে টিসিপি পোর্ট বাঁধার আগে কার্যকর করা দরকার - যেমন কনফিগার বা ডেটা যা ডিবি থেকে পড়তে হয় যা এ্যাসিঙ্ক খোলা হয়? আমি ফাইবারে পুরো সার্ভার.জগুলি মোড়ক দিয়ে শেষ করতে পারি এবং আমার সন্দেহ হয় যে পুরো প্রক্রিয়া স্তরে সম্মতি মুছে ফেলবে। তবুও এটি একটি পরামর্শ যা যাচাই করার জন্য মূল্যবান। আমার কাছে আদর্শ সমাধানটি একটি সিঙ্ক কল সিনট্যাক্স সরবরাহ করতে একটি অ্যাসিঙ্ক ফাংশনটি গুটিয়ে রাখতে সক্ষম হতে হবে এবং প্রক্রিয়া পর্যায়ে একমত পোষণ না করে কলার চেইনে কেবল কোডের পরবর্তী লাইনগুলি ব্লক করে।
সংক্ষিপ্তকরণ

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

আমি এক্সপ্রেস বুটস্ট্র্যাপ ফাইল সার্ভার.জগুলি ফাইবারের সাথে আবৃত করেছি। মৃত্যুদন্ডের ক্রমটি আমি যা খুঁজছি, তবে অনুরোধ হ্যান্ডলারের উপর এই মোড়কের কোনও প্রভাব নেই। সুতরাং আমি অনুমান করি যে প্রতিটি প্রেরককে একই র‍্যাপারটি প্রয়োগ করতে হবে। আমি এই মুহুর্তে হাল ছেড়ে দিয়েছি কারণ বৈশ্বিক পুনঃ-ফ্যাক্টরিং এড়াতে সহায়তার জন্য এটি আরও ভাল কিছু করার বলে মনে হচ্ছে না। আমার উদ্দেশ্য হ'ল কলকারীর উপর প্রভাব হ্রাস করা যখন ডেটা অধিগ্রহণের পদ্ধতিটি সিএনএ থেকে ডিএও স্তরতে অ্যাসিঙ্কে পরিবর্তিত হয় এবং ফাইবার এখনও চ্যালেঞ্জের থেকে কিছুটা ছোট হয়ে যায়।
সংক্ষিপ্তকরণ

@ ফ্রেড: অনুরোধ হ্যান্ডলারের মতো ইভেন্ট স্ট্রিমগুলিকে "সিঙ্ক্রোনাইজ" করার পক্ষে খুব বেশি অর্থ হয় না - আপনার একটি while(true) handleNextRequest()লুপ থাকা দরকার। প্রতিটি অনুরোধ হ্যান্ডলারের একটি ফাইবারে মোড়ানো would
বার্গি

@fred: তন্তু আপনি অনেক সাহায্য করবে না Express এর সাথে কারণ এক্সপ্রেস 'কলব্যাক হয় না ধারাবাহিকতায় কলব্যাক (ক কলব্যাক যে সবসময় ঠিক একবার বলা হয়, হয় একটি ত্রুটি সহ বা ফলে সহ)। ক্রমাগত কলব্যাকস (যেমন, এফএস, মঙ্গোডব, এবং আরও অনেকগুলি) সহ আপনারা যখন এ্যাসএনসি এপিআইয়ের উপরে প্রচুর কোড লেখা থাকে তখন ফাইবারগুলি ডুমের পিরামিডটি সমাধান করবে।
ব্রুনো জোহির

-2

আমি প্রথমে node.js এর সাথে এটির সাথে লড়াই করেছি এবং async.js এটির সাথে লেনদেন করার জন্য আমি খুঁজে পাওয়া সেরা লাইব্রেরি। আপনি যদি নোডের সাথে সিঙ্ক্রোনাস কোডটি লিখতে চান তবে পদ্ধতির উপায় এই।

var async = require('async');

console.log('in main');

doABunchOfThings(function() {
  console.log('back in main');
});

function doABunchOfThings(fnCallback) {
  async.series([
    function(callback) {
      console.log('step 1');
      callback();
    },
    function(callback) {
      setTimeout(callback, 1000);
    },
    function(callback) {
      console.log('step 2');
      callback();
    },
    function(callback) {
      setTimeout(callback, 2000);
    },
    function(callback) {
      console.log('step 3');
      callback();
    },
  ], function(err, results) {
    console.log('done with things');
    fnCallback();
  });
}

এই প্রোগ্রামটি সর্বদা নিম্নলিখিত উত্পাদন করবে ...

in main
step 1
step 2
step 3
done with things
back in main

2
asyncএটি আপনার খ / সি উদাহরণে কাজ mainকরে, যা কলারের বিষয়ে চিন্তা করে না। কল্পনা করুন যে আপনার সমস্ত কোড কোনও ফাংশনে মোড়ানো রয়েছে যা আপনার কোনও অ্যাসিঙ্ক ফাংশন কলগুলির ফলাফল ফেরত দেওয়ার কথা is এটি সহজেই console.log('return');আপনার কোডের শেষে যুক্ত করে কাজ না করে প্রমাণ করা যায় । এই ক্ষেত্রে এর আউটপুট returnপরে in mainকিন্তু আগে হবে step 1
এবিআর

-11

জাভাস্ক্রিপ্ট একক থ্রেডেড ভাষা, আপনি আপনার পুরো সার্ভারটি ব্লক করতে চান না! অ্যাসিঙ্ক কোডটি নির্ভরতা সুস্পষ্ট করে বর্ণের শর্তগুলি সরিয়ে দেয়।

অ্যাসিক্রোনাস কোড পছন্দ করতে শিখুন!

promisesকলব্যাক হেলকের পিরামিড তৈরি না করে অ্যাসিক্রোনাস কোডের জন্য একবার দেখুন । আমি node.js এর জন্য প্রতিশ্রুতিবদ্ধ লাইব্রেরিটি সুপারিশ করছি

httpGet(url.parse("http://example.org/")).then(function (res) {
    console.log(res.statusCode);  // maybe 302
    return httpGet(url.parse(res.headers["location"]));
}).then(function (res) {
    console.log(res.statusCode);  // maybe 200
});

http://howtonode.org/promises

সম্পাদনা: এটি এখন পর্যন্ত আমার সবচেয়ে বিতর্কিত উত্তর, নোডে এখন ফলন কীওয়ার্ড রয়েছে, যা আপনাকে অ্যাসিঙ্ক কোডটি এমনভাবে আচরণ করতে দেয় যেন এটি সিক্রোনাস। http://blog.alexmaccaw.com/how-yield-will-transform-node


1
প্রতিশ্রুতি কেবল ফাংশনটিকে সিঙ্কে রূপান্তর না করে কেবল একটি কলব্যাক প্যারামিটারকে পুনরায় প্রতিস্থাপন করে।
সংক্ষিপ্তকরণ

2
আপনি এটি সিঙ্ক করতে চান না বা আপনার পুরো সার্ভারটি ব্লক হয়ে যাবে! stackoverflow.com/questions/17959663/...
roo2

1
যা প্রয়োজন তা হ'ল নোড.জেএস দ্বারা পরিচালিত অন্য অনুরোধের মতো অন্য ইভেন্টগুলিকে অবরুদ্ধ না করে একটি সিঙ্ক কল is সংজ্ঞা অনুসারে একটি সিঙ্ক ফাংশনটির অর্থ হ'ল ফলাফল না আসা পর্যন্ত এটি কলারে ফিরে আসবে না (নিছক প্রতিশ্রুতি নয়)। এটি কল অবরুদ্ধ অবস্থায় অন্যান্য ইভেন্টগুলি পরিচালনা থেকে সার্ভারটিকে প্রাক-বর্জন করে না।
সংক্ষিপ্তকরণ

@fred: আমার মনে হয় আপনি প্রতিশ্রুতি বিন্দু দিতে ভুলে গেছেন । এগুলি কেবল একটি পর্যবেক্ষক প্যাটার্ন বিমূর্ততা নয়, তবে তারা শৃঙ্খলাবদ্ধ এবং অ্যাসিঙ্ক্রোনাস ক্রিয়া রচনা করার একটি উপায় সরবরাহ করে।
বার্গি

1
বার্গি, আমি অনেক প্রতিশ্রুতি ব্যবহার করি এবং এটি ঠিক কী করে তা জানি। কার্যকরভাবে এটি অর্জন করা সমস্তগুলি একক অ্যাসিঙ্ক ফাংশন অনুরোধকে একাধিক অনুরোধ / বিবৃতিতে ভেঙে দেয়। তবে এটি ফলাফল পরিবর্তন করে না - কলার ফিরে আসার পরে এটি অ্যাসিঙ্ক ফাংশনের ফলাফলটি ফিরিয়ে দিতে পারে না। আমি জেএসফিডেলে পোস্ট করা উদাহরণটি দেখুন। সেক্ষেত্রে কলারটি ফাংশন অ্যান্টিপিকেটেডসাইঙ্কফিউশন এবং অ্যাসিঙ্ক ফাংশন সেটটাইমআউট হয়। আপনি যদি প্রতিশ্রুতি ব্যবহার করে আমার চ্যালেঞ্জের উত্তর দিতে পারেন তবে দয়া করে আমাকে দেখান।
সংক্ষিপ্তকরণ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.