আমি কখন jQuery স্থগিতের "তারপরে" পদ্ধতিটি ব্যবহার করব এবং কখন "পাইপ" পদ্ধতিটি ব্যবহার করব?


97

jQuery এর Deferredদুটি ফাংশন রয়েছে যা ফাংশনগুলির অ্যাসিনক্রোনাস চেইন প্রয়োগ করতে ব্যবহার করা যেতে পারে:

then()

deferred.then( doneCallbacks, failCallbacks ) Returns: Deferred

ডেলক্যালব্যাকস একটি ফাংশন, বা ফাংশনগুলির অ্যারে, যখন মুলতুবি সমাধান করা হয় called
ফেলক্যালব্যাকস একটি ফাংশন, বা ডিফল্ট প্রত্যাখ্যান করা হলে ফাংশনগুলির অ্যারে।

pipe()

deferred.pipe( [doneFilter] [, failFilter] ) Returns: Promise

সম্পন্ন ফিল্টার একটি alচ্ছিক ফাংশন যা ডারফার্ড সমাধান হওয়ার পরে ডাকা হয়।
ফেলফিল্টার একটি alচ্ছিক ফাংশন যা ডারফার্ড প্রত্যাখ্যাত হলে ডাকা হয়।

আমি জানি then()যে এর চেয়ে আরও কিছুটা দীর্ঘ সময় হয়েছে pipe()তবে পরবর্তীকর্তাকে অবশ্যই কিছু অতিরিক্ত বেনিফিট যুক্ত করতে হবে, তবে পার্থক্যটি স্পষ্টতই আমাকে অন্তর্ভুক্ত করে। উভয়ই একই কলব্যাকের পরামিতিগুলি গ্রহণ করে যদিও তারা নামের সাথে পৃথক হয় এবং একটি Deferredফেরত দেওয়া এবং ফেরত দেওয়ার মধ্যে পার্থক্য Promiseসামান্য মনে হয়।

আমি সরকারী দস্তাবেজগুলি বারবার পড়েছি তবে সবসময় তাদের খুব "ঘন" বলে আমার মাথা ঘিরে রাখে এবং অনুসন্ধানে একটি বৈশিষ্ট্য বা অন্যটির প্রচুর আলোচনার সন্ধান পেয়েছে তবে আমি এমন কিছু খুঁজে পাইনি যা সত্যই আলাদাভাবে স্পষ্ট করে প্রতিটি ভাল এবং কনস।

সুতরাং কখন এটি ব্যবহার করা ভাল thenএবং কখন এটি ব্যবহার করা ভাল pipe?


সংযোজন

ফেলিক্সের দুর্দান্ত উত্তরটি এই দুটি ফাংশন কীভাবে পৃথক রয়েছে তা স্পষ্ট করে বলতে সহায়তা করেছে। কিন্তু আমি ভাবছি যদি সেখানে বার যখন কার্যকারিতা then()যে বাঞ্ছনীয় pipe()

এটি স্পষ্টত যা pipe()তার চেয়ে বেশি শক্তিশালী then()এবং মনে হয় প্রাক্তন পরবর্তীকালে কিছু করতে পারে। ব্যবহারের একটি কারণ then()হতে পারে এটির নাম একই ডেটা প্রক্রিয়াজাতকরণের একটি শৃঙ্খলা সমাপ্তির ভূমিকা হিসাবে এর ভূমিকা প্রতিবিম্বিত করে।

তবে এমন কোনও ব্যবহারের কেস রয়েছে যার জন্য then()নতুনটি ফেরার কারণে এটি Deferredকরা যায় না এমন আসলটি ফেরত দেওয়া দরকার ?pipe()Promise


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

6
এই প্রশ্নের আগ্রহী যে কেউ নিশ্চয় jQuery এর বাগ যে ব্যক্তি অনুসরণ করে উপর টিকেট # 11010 আগ্রহী হতে হবে: করতে DEFERRED.THEN == DEFERRED.PIPE মত প্রতিজ্ঞা / এ
hippietrail

উত্তর:


103

যেহেতু jQuery 1.8 .then একই আচরণ করে .pipe:

অবমূল্যায়নের বিজ্ঞপ্তি: jQuery 1.8 হিসাবে, deferred.pipe()পদ্ধতিটি অবচয় করা হয়েছে। deferred.then()পদ্ধতি, যা তা পরিবর্ত পরিবর্তে ব্যবহার করা উচিত।

এবং

JQuery এর 1.8 এর হিসাবে , deferred.then()পদ্ধতি একটি নতুন অঙ্গীকার করা হয়েছে যে অবস্থা এবং একটি একটি ফাংশন মাধ্যমে বিলম্বিত মান ফিল্টার করতে পারে, এখন অবচিত প্রতিস্থাপন ফেরৎ deferred.pipe()পদ্ধতি।

নীচের উদাহরণগুলি এখনও কারও জন্য সহায়ক হতে পারে।


তারা বিভিন্ন উদ্দেশ্যে পরিবেশন করে:

  • .then()আপনি যখনই প্রক্রিয়াটির ফলাফলের সাথে কাজ করতে চান তখনই ব্যবহার করতে হয়, যেমন ডকুমেন্টেশন যেমন বলে, যখন পিছিয়ে দেওয়া বস্তুটি সমাধান বা প্রত্যাখ্যাত হয়। এটি ব্যবহার .done()বা হিসাবে একই .fail()

  • আপনি কোনওভাবে ফলাফল ফিল্টার.pipe() করতে (প্রাক) ব্যবহার করতেন । একটি কলব্যাক ফেরত মান থেকে আর্গুমেন্ট হিসাবে পাস হবে এবং callbacks। এটি অন্য একটি স্থগিত বস্তুটিও ফিরিয়ে দিতে পারে এবং নিম্নলিখিত মুলতুবিতে নিম্নলিখিত কলব্যাকগুলি নিবন্ধিত হবে।.pipe()donefail

    .then()(বা .done(), .fail()) ক্ষেত্রে এটি নয় , নিবন্ধিত কলব্যাকগুলির রিটার্ন মানগুলি কেবল উপেক্ষা করা হবে।

সুতরাং আপনি এটি ব্যবহার করেন বা হয় না যে । আপনি একই উদ্দেশ্যে যেমন ব্যবহার করতে পারেন তবে কনভার্সটি ধারণ করে না।.then() .pipe().pipe().then()


উদাহরণ 1

কিছু ক্রিয়াকলাপের ফলাফল হ'ল বস্তুর একটি অ্যারে:

[{value: 2}, {value: 4}, {value: 6}]

এবং আপনি সর্বনিম্ন এবং সর্বাধিক মানগুলি গণনা করতে চান। ধরে নেওয়া যাক আমরা দুটি doneকলব্যাক ব্যবহার করি :

deferred.then(function(result) {
    // result = [{value: 2}, {value: 4}, {value: 6}]

    var values = [];
    for(var i = 0, len = result.length; i < len; i++) {
        values.push(result[i].value);
    }
    var min = Math.min.apply(Math, values);

   /* do something with "min" */

}).then(function(result) {
    // result = [{value: 2}, {value: 4}, {value: 6}]

    var values = [];
    for(var i = 0, len = result.length; i < len; i++) {
        values.push(result[i].value);
    }
    var max = Math.max.apply(Math, values);

   /* do something with "max" */ 

});

উভয় ক্ষেত্রে আপনাকে তালিকাটি পুনরাবৃত্তি করতে হবে এবং প্রতিটি বস্তুর থেকে মানটি বের করতে হবে।

আপনি যদি কোনওভাবেই দুটি কলব্যাকগুলিতে স্বতন্ত্রভাবে না করতে চান তবে কোনওভাবে আগে থেকেই মানগুলি বের করে নেওয়া ভাল না? হ্যাঁ! এবং এটিই আমরা এর .pipe()জন্য ব্যবহার করতে পারি :

deferred.pipe(function(result) {
    // result = [{value: 2}, {value: 4}, {value: 6}]

    var values = [];
    for(var i = 0, len = result.length; i < len; i++) {
        values.push(result[i].value);
    }
    return values; // [2, 4, 6]

}).then(function(result) {
    // result = [2, 4, 6]

    var min = Math.min.apply(Math, result);

    /* do something with "min" */

}).then(function(result) {
    // result = [2, 4, 6]

    var max = Math.max.apply(Math, result);

    /* do something with "max" */

});

স্পষ্টতই এটি একটি তৈরি উদাহরণ এবং এই সমস্যাটি সমাধানের বিভিন্ন (সম্ভবত আরও ভাল) উপায় রয়েছে তবে আমি আশা করি এটি বিষয়টি ব্যাখ্যা করবে।


উদাহরণ 2

Ajax কল বিবেচনা করুন। কখনও কখনও আপনি পূর্ববর্তীটি সম্পূর্ণ হওয়ার পরে একটি এজ্যাক কল শুরু করতে চান। একটি উপায় doneকলব্যাকের মধ্যে দ্বিতীয় কল করা :

$.ajax(...).done(function() {
    // executed after first Ajax
    $.ajax(...).done(function() {
        // executed after second call
    });
});

এখন ধরে নেওয়া যাক আপনি আপনার কোডটি ডিকুয়াল করতে চান এবং একটি ফাংশনের ভিতরে এই দুটি অ্যাজাক্স কল রাখতে চান:

function makeCalls() {
    // here we return the return value of `$.ajax().done()`, which
    // is the same deferred object as returned by `$.ajax()` alone

    return $.ajax(...).done(function() {
        // executed after first call
        $.ajax(...).done(function() {
            // executed after second call
        });
    });
}

আপনি দ্বিতীয় অ্যাজ্যাক্স কলের makeCallsজন্য কলব্যাকগুলি সংযুক্ত করার জন্য কল করে এমন কোডের অনুমতি দেওয়ার জন্য মুলতুবি বস্তুটি ব্যবহার করতে চান , তবে

makeCalls().done(function() {
    // this is executed after the first Ajax call
});

দ্বিতীয় কলটি doneকলব্যাকের ভিতরে করা এবং বাইরে থেকে অ্যাক্সেসযোগ্য না হওয়ায় কাঙ্ক্ষিত প্রভাব পড়বে না।

.pipe()পরিবর্তে সমাধানটি ব্যবহার করা হবে:

function makeCalls() {
    // here we return the return value of `$.ajax().pipe()`, which is
    // a new deferred/promise object and connected to the one returned
    // by the callback passed to `pipe`

    return $.ajax(...).pipe(function() {
        // executed after first call
        return $.ajax(...).done(function() {
            // executed after second call
        });
    });
}

makeCalls().done(function() {
    // this is executed after the second Ajax call
});

ব্যবহারের মাধ্যমে .pipe()আপনি এখন কলগুলির প্রকৃত প্রবাহ / ক্রমটি প্রকাশ না করেই "অভ্যন্তরীণ" অ্যাজাক্স কলটিতে কলব্যাক যুক্ত করতে পারবেন।


সাধারণভাবে, বিলম্বিত বস্তুগুলি আপনার কোডটি ডিক্লোল করার একটি আকর্ষণীয় উপায় সরবরাহ করে :)


আহ হ্যাঁ আমি উপেক্ষা করেছি যা pipeফিল্টারিং করতে thenপারে যা করতে পারে না। তবে এই বিষয়গুলি গুগলিংয়ে দেখে মনে হয় যে তারা ফিল্টারিংকে বোনাসের অতিরিক্ত হিসাবে বিবেচনা করেছিল, pipeবরং filterএটি pipeআরও স্পষ্টভাবে তার আসল উদ্দেশ্যটি ইঙ্গিত করেছে বলেই তারা এটিকে কল করেছে । সুতরাং এটি ফিল্টারিং ছাড়াও অন্যান্য পার্থক্য থাকা উচিত বলে মনে হয়। (তারপর আবার আমি স্বীকার আমি সত্যিই এমনকি আপনার উদাহরণ ফিল্টারিং বৈশিষ্ট্যটি বুঝতে পারছি না হবে। result values;হতে return values;প্রণালী দ্বারা?)
hippietrail

যখন আমি বলি যে আমি আপনার উদাহরণগুলি বুঝতে পারি না, এটি কি এরকম কিছু: উচ্চ উদাহরণে, দু'জন .then()একই ডাটা পাবেন resultযা আপনি প্রতিবার ফিল্টার করেন; যদিও নীচের উদাহরণে, পরবর্তী দুটি এই দুটি গ্রহণ করবে তা পাস করার আগে এর .pipe()কিছু তথ্য মুছে ফেলে ? resultresult.then()
হিপ্পিট্রেইল

4
@ হিপ্পিট্রেইল: আমি এর মধ্যে আমার উত্তর আপডেট করেছি এবং এর অন্যান্য উদ্দেশ্যগুলিও অন্তর্ভুক্ত করেছি .pipe()। যদি কলব্যাক একটি স্থগিত বস্তুটি ফেরত দেয় তবে পরবর্তীকৃত বা ব্যর্থ কলব্যাকগুলি সেই বস্তুর জন্য নিবন্ধিত হবে। আমি অন্য একটি উদাহরণ অন্তর্ভুক্ত করব। সম্পাদনা: আপনার দ্বিতীয় মন্তব্য সম্পর্কিত: হ্যাঁ।
ফেলিক্স ক্লিং

সুতরাং একটি পার্থক্য হ'ল ডেটা প্রবাহিত হয় pipe() যেখানে then()আরও একটি পাতার নোডের শেষে থাকে যার শেষে আপনাকে অবশ্যই আপনার ডেটা ব্যবহার করতে হবে এবং এটি আরও প্রবাহিত হয় না, এবং যে কোনও তথ্য then()ফেরত Deferredআসলেও এটি ব্যবহার / কার্যকর নয়? যদি এটি সঠিক হয় তবে এটি /* do something with "min"/"max" */প্রতিটি ".ত () ধারা" এর মধ্যে কিছু অন্তর্ভুক্ত করার জন্য স্পষ্ট করতে সহায়তা করতে পারে ।
হিপ্পিট্রেইল

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

7

এমন কোনও ঘটনা নেই যেখানে আপনার then()বেশি ব্যবহার করা উচিত pipe()। আপনি যে মানটি pipe()পাস হবে তা এড়াতে সর্বদা চয়ন করতে পারেন using ব্যবহারের জন্য সামান্য পারফরম্যান্স হিট হতে পারে pipe- তবে এটি গুরুত্ব পাবে না।

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

এটি এমন একটি ফাংশন থাকার মতো যা এমন কোনও মান দেয় যা কখনই ব্যবহৃত হয় না: বিভ্রান্তিকর।

সুতরাং then()কখন আপনার উচিত এবং pipe()কখন আপনার উচিত ... ব্যবহার করুন


4
স্কট অ্যালেনের ব্লগ, "রাইটিং ইন এক্সপেরিমেন্টস": জিওলোকেশন, জিওকোডিং, এবং জিকুয়ের প্রতিশ্রুতি : দুটি ব্যবহার করে আমি একটি বাস্তব জীবনের উদাহরণ পেয়েছি : "তারপরে নিয়ন্ত্রণের যুক্তিটি বেশ ভালভাবে পড়ে:" $(function () { $.when(getPosition()) .pipe(lookupCountry) .then(displayResults); }); "নোট করুন যে পাইপটি এর চেয়ে আলাদা তারপরে যেহেতু পাইপ নতুন প্রতিশ্রুতি দেয়। "
হিপ্পিট্রেইল

5

আসলে এটা দেখা যাচ্ছে যে এর মধ্যে পার্থক্য .then()এবং .pipe()অপ্রয়োজনীয় গণ্য করা হয়েছে এবং তারা jQuery এর সংস্করণ 1.8 হিসাবে একই হতে হয়েছে।

JQuery এর বাগ ট্র্যাকার টিকিট # 11010 এর একটি মন্তব্যjaubourg থেকে "মেকার ডিফারড.এইচটিএন == ডিফ্রেড.পিপ লাইক প্রাইমেস / এ" করুন:

1.8 এ, আমরা তখনকার পুরানোটি সরিয়ে ফেলা করব এবং এটি বর্তমান পাইপ দিয়ে প্রতিস্থাপন করব। তবে অত্যন্ত দুঃখজনক পরিণতিটি হ'ল আমাদের লোকজনকে মানহীন সম্পন্ন, ব্যর্থতা এবং অগ্রগতি ব্যবহার করতে বলতে হবে, কারণ প্রস্তাবটি সহজ, EFFICIENT প্রদান করে না, কেবল একটি কলব্যাক যোগ করার অর্থ।

(এমফ্যাসিস মাইন)


4
এখনও অবধি সেরা রেফারেন্স, আমি উন্নত ব্যবহারের সন্ধান করছি।
TWiStErRob
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.