কীভাবে jQuery মুলতুবি ব্যবহার করা যেতে পারে?


279

jQuery এর 1.5 নতুন বিলম্বিত বস্তু এবং সংযুক্ত পদ্ধতি এনেছে .when, .Deferredএবং ._Deferred

যারা .Deferredআগে ব্যবহার করেন নি, তাদের জন্য আমি উত্সটি বর্নিত করেছি ।

এই নতুন পদ্ধতির সম্ভাব্য ব্যবহারগুলি কী কী, আমরা কীভাবে সেগুলিকে নিদর্শনগুলির মধ্যে ফিট করতে পারি?

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

আমার কাছে একটি বাফার ক্লাসের একটি সাধারণ উদাহরণ রয়েছে যা AJAX অনুরোধটিকে ক্রমে কল করে। (পূর্ববর্তীটি শেষ হওয়ার পরে পরবর্তী একটি শুরু)।

/* Class: Buffer
 *  methods: append
 *
 *  Constructor: takes a function which will be the task handler to be called
 *
 *  .append appends a task to the buffer. Buffer will only call a task when the 
 *  previous task has finished
 */
var Buffer = function(handler) {
    var tasks = [];
    // empty resolved deferred object
    var deferred = $.when();

    // handle the next object
    function handleNextTask() {
        // if the current deferred task has resolved and there are more tasks
        if (deferred.isResolved() && tasks.length > 0) {
            // grab a task
            var task = tasks.shift();
            // set the deferred to be deferred returned from the handler
            deferred = handler(task);
            // if its not a deferred object then set it to be an empty deferred object
            if (!(deferred && deferred.promise)) {
                deferred = $.when();
            }
            // if we have tasks left then handle the next one when the current one 
            // is done.
            if (tasks.length > 0) {
                deferred.done(handleNextTask);
            }
        }
    }

    // appends a task.
    this.append = function(task) {
        // add to the array
        tasks.push(task);
        // handle the next task
        handleNextTask();
    };
};

আমি বিক্ষোভ এবং এর সম্ভাব্য ব্যবহারগুলি .Deferredএবং এর সন্ধান করছি .when

এটি উদাহরণগুলি দেখতে ভাল লাগবে ._Deferred

jQuery.ajaxউদাহরণের জন্য নতুন উত্সের সাথে লিঙ্ক করা প্রতারণা।

কোনও অপারেশন সুসংগতভাবে বা অবিচ্ছিন্নভাবে সম্পন্ন হয়েছে কিনা তা আমরা যখন অ্যাবস্ট্রাক্ট করি তখন কী কৌশল উপলব্ধ তা সম্পর্কে আমি বিশেষভাবে আগ্রহী।


19
এফএকিউ থেকে: সাবজেক্টিভ প্রশ্ন জিজ্ঞাসা করবেন না যেখানে প্রতিটি উত্তর সমানভাবে বৈধ: "আপনার প্রিয় ______ কি?" (তাদের জোর)
টিজে ক্রোডার

2
@ টিজেক্রোজার আমি এটি পুনর্নির্মাণের দিকে নজর দেব।
রায়নোস

5
এটা একটা ভাল প্রশ্ন কিন্তু হতে পারে না যে অনেক মানুষ যারা উত্তর দিতে পারেন :-)
সূচালো

2
@ পয়েন্টে আমি মূলত যারা তৃতীয় পক্ষের প্লাগইন ছিল তখন যারা এটি ব্যবহার করেছেন তাদের দিকে তাকিয়ে আছি। এবং জনগণকে বসতে এবং এটি ব্যবহার করতে উত্সাহিত করছে!
রায়নোস

1
._Deferredকেবলমাত্র সত্য "ডিফার্ড অবজেক্ট" যা .Deferredব্যবহার করে। এটি একটি অভ্যন্তরীণ অবজেক্ট যা আপনার সম্ভবত কখনও প্রয়োজন হবে না।
ডেভিড টাং

উত্তর:


212

আমি যে সর্বোত্তম ব্যবহারের বিষয়টি ভাবতে পারি তা হ'ল এজেএক্স প্রতিক্রিয়াগুলি ক্যাশে করা। এই বিষয়টিতে রেবেকা মারফির অন্তর্ভুক্ত পোস্টের একটি পরিবর্তিত উদাহরণ এখানে রয়েছে :

var cache = {};

function getData( val ){

    // return either the cached value or jqXHR object wrapped Promise
    return $.when(
        cache[ val ] || 
        $.ajax('/foo/', {
            data: { value: val },
            dataType: 'json',
            success: function( resp ){
                cache[ val ] = resp;
            }
        })
    );
}

getData('foo').then(function(resp){
    // do something with the response, which may
    // or may not have been retrieved using an
    // XHR request.
});

মূলত, যদি ক্যাশে থেকে তাৎক্ষণিকভাবে ফিরে আসার আগে মানটি ইতিমধ্যে একবার অনুরোধ করা হয়েছিল। অন্যথায়, একটি এজেএক্স অনুরোধ ডেটাটি আনে এবং এটি ক্যাশে যুক্ত করে। $.when/ .thenএই কোন যত্ন সম্পর্কে না; আপনার যে সমস্ত বিষয়ে উদ্বিগ্ন হওয়া দরকার তা হ'ল প্রতিক্রিয়াটি ব্যবহার করা, যা .then()উভয় ক্ষেত্রেই হ্যান্ডলারের কাছে প্রেরণ করা হয় । jQuery.when()অবিলম্বে কোনও .done()বা .then()শৃঙ্খলে কার্যকর করে একটি সম্পূর্ণ-হিসাবে একটি অ-প্রতিশ্রুতি / স্থগিত পরিচালনা করে ।

যখন কার্যটি অযৌক্তিকভাবে কাজ করতে পারে বা না পারে তখন জন্য ডিফার্ডগুলি উপযুক্ত and এবং আপনি কোডটি বাদ দিয়ে এই শর্তটি বিমূর্ত করতে চান।

সহায়ককে ব্যবহার করে আরও একটি বাস্তব বিশ্বের উদাহরণ $.when:

$.when($.getJSON('/some/data/'), $.get('template.tpl')).then(function (data, tmpl) {

    $(tmpl) // create a jQuery object out of the template
    .tmpl(data) // compile it
    .appendTo("#target"); // insert it into the DOM

});

4
দুটি উজ্জ্বল উদাহরণ। আমি ২ য়টির অনুরূপ কিছু বাস্তবায়ন করেছি, তবে ৪ টি অজ্যাক্স অনুরোধের সাথে এবং এটি আরও কার্যকর, কমপ্যাক্ট, লজিক, রক্ষণাবেক্ষণযোগ্য ইত্যাদি ছাড়াও ভাল সম্পাদন করে j jQuery.Deferred একটি সত্যই ভাল জিনিস।
পিজেপি

5
এখানে এই বিষয়টির একটি দরকারী ভিডিও এখানে রয়েছে bigbinary.com/videos/3- using
নিক ভ্যান্ডারবিল্ট

5
ফলাফল মিথ্যা মান হলে ক্যাশিং কাজ করবে না। এছাড়াও আমি পছন্দ করি না যে getData নেওয়া শাখার উপর নির্ভর করে 2 বিভিন্ন ধরণের ফেরত দেয়।
মার্কো ডুমিক

3
এজ্যাক্স ক্যাচিংয়ের আরও ভাল প্রয়োগের জন্য নীচে জুলিয়ান ডি এর উত্তর দেখুন।
ইভেন্ট_জেআর

1
আমি বুঝতে পারি না যে প্রথম কোড উদাহরণটি এমনকি কীভাবে কাজ করে: আমি সেই জিনিসটি বুঝতে পারি যেখানে অবজেক্টটি ক্যাশে করা হয়নি, তবে তা যদি cache[ val ]কোনও প্রতিশ্রুতি না ফেরায় (জ্যাকুরি ডকুমেন্টেশন বলে যে প্যারামিটারটি প্রেরকের দ্বারা ফিরিয়ে নেওয়া ডেটা হয়) যার অর্থ সদস্যের অ্যাক্সেসে .thenউইল ত্রুটি হবে ... তাই না? আমি কী মিস করছি?
চচাম 15

79

এখানে এহ্যাক্সের উত্তরের মতো একটি এজেএক্স ক্যাশেটির কিছুটা আলাদা বাস্তবায়ন রয়েছে ।

ফরচুনরাইসের ফলো-আপ প্রশ্নে উল্লিখিত হিসাবে , অনুরোধগুলির কোনও একটি ফিরে আসার আগে যদি অনুরোধগুলি সম্পাদন করা হত তবে অহিদের বাস্তবায়ন একাধিক অভিন্ন অনুরোধগুলিকে আটকাতে পারেনি। এটাই,

for (var i=0; i<3; i++) {
    getData("xxx");
}

"এক্সএক্সএক্সএক্স" এর ফলাফল ইতিমধ্যে ক্যাশে না করা হলে সম্ভবত 3 টি এজেএক্স অনুরোধের ফলাফল হবে।

ফলাফলের পরিবর্তে অনুরোধের ডিফার্ডগুলি ক্যাশে করে সমাধান করা যেতে পারে:

var cache = {};

function getData( val ){

    // Return a promise from the cache (if available)
    // or create a new one (a jqXHR object) and store it in the cache.
    var promise = cache[val];
    if (!promise) {
        promise = $.ajax('/foo/', {
            data: { value: val },
            dataType: 'json'
        });
        cache[val] = promise;
    }
    return promise;
}

$.when(getData('foo')).then(function(resp){
    // do something with the response, which may
    // or may not have been retreived using an
    // XHR request.
});

1
আমি মনে করি এটি এখনও নিখুঁত নয়, যেহেতু আপনি প্রথমবার একবার এনে ক্যাশে সাফ / আপডেট করেন না। এটি এজেএক্স কলকে কোনও আপডেটের জন্য কাজ করছে না।
জাইজিস

45

একটি মুলতুবি জায়গায় স্থগিত করা যেতে পারে। এটি মূলত একাধিক এজ্যাক্স ব্যবহারের পরিস্থিতিগুলির মতো।

mutex

var mutex = 2;

setTimeout(function() {
 callback();
}, 800);

setTimeout(function() {
 callback();
}, 500);

function callback() {
 if (--mutex === 0) {
  //run code
 }
}

বিলম্বিত

function timeout(x) {
 var dfd = jQuery.Deferred();
 setTimeout(function() {
  dfd.resolve();
 }, x);
 return dfd.promise();
}

jQuery.when(
timeout(800), timeout(500)).done(function() {
 // run code
});

যখন কোনও ডিফার্ডকে কেবলমাত্র মিউটেক্স হিসাবে ব্যবহার করা হয়, তখন পারফরম্যান্সের প্রভাবগুলির জন্য নজর রাখুন (http://jsperf.com/deferred-vs-mutex/2)। যদিও ডিফার্ড দ্বারা সরবরাহ করা অতিরিক্ত সুবিধাগুলি পাশাপাশি যথাযথ মূল্যবান এবং প্রকৃতপক্ষে (ব্যবহারকারী দ্বারা চালিত ইভেন্ট ভিত্তিক) ব্যবহারের ক্ষেত্রে পারফরম্যান্স প্রভাবটি লক্ষণীয় হওয়া উচিত নয়।


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

28

এটি একটি স্ব-প্রচারমূলক উত্তর, তবে আমি এটি গবেষণা করে কয়েক মাস ব্যয় করেছি এবং jQuery সম্মেলন সান ফ্রান্সিসকো 2012-এ ফলাফল উপস্থাপন করেছি।

এখানে আলাপের একটি বিনামূল্যে ভিডিও:

https://www.youtube.com/watch?v=juRtEEsHI9E


20

আরেকটি ব্যবহার যা আমি ভাল উদ্দেশ্যে রেখেছি তা হ'ল একাধিক উত্স থেকে ডেটা আনা। নীচের উদাহরণে, আমি ক্লায়েন্ট এবং একটি REST সার্ভারের মধ্যে বৈধতার জন্য একটি বিদ্যমান অ্যাপ্লিকেশনটিতে ব্যবহৃত একাধিক, স্বতন্ত্র জেএসওএন স্কিমা অবজেক্ট আনছি। এই ক্ষেত্রে, আমি চাই না যে ব্রাউজারের পাশের অ্যাপ্লিকেশনটিতে সমস্ত স্কিমা লোড হওয়ার আগে ডেটা লোড করা শুরু করা উচিত। w। যখন (অ্যাপ্লিকেশন) (তখন।) এর জন্য উপযুক্ত। ত্রুটির অবস্থার জন্য নিরীক্ষণ করতে তখন (fn1, fn2) ব্যবহারের নির্দেশকের জন্য রায়নোসকে ধন্যবাদ জানাই।

fetch_sources = function (schema_urls) {
    var fetch_one = function (url) {
            return $.ajax({
                url: url,
                data: {},
                contentType: "application/json; charset=utf-8",
                dataType: "json",
            });
        }
    return $.map(schema_urls, fetch_one);
}

var promises = fetch_sources(data['schemas']);
$.when.apply(null, promises).then(

function () {
    var schemas = $.map(arguments, function (a) {
        return a[0]
    });
    start_application(schemas);
}, function () {
    console.log("FAIL", this, arguments);
});     

10

Deferredকোনও ধরণের গণনার জন্য ক্যাশে প্রয়োগ করার জন্য s ব্যবহার করে অন্য একটি উদাহরণ (সাধারণত কিছু কার্য সম্পাদন-নিবিড় বা দীর্ঘ-চলমান কার্য):

var ResultsCache = function(computationFunction, cacheKeyGenerator) {
    this._cache = {};
    this._computationFunction = computationFunction;
    if (cacheKeyGenerator)
        this._cacheKeyGenerator = cacheKeyGenerator;
};

ResultsCache.prototype.compute = function() {
    // try to retrieve computation from cache
    var cacheKey = this._cacheKeyGenerator.apply(this, arguments);
    var promise = this._cache[cacheKey];

    // if not yet cached: start computation and store promise in cache 
    if (!promise) {
        var deferred = $.Deferred();
        promise = deferred.promise();
        this._cache[cacheKey] = promise;

        // perform the computation
        var args = Array.prototype.slice.call(arguments);
        args.push(deferred.resolve);
        this._computationFunction.apply(null, args);
    }

    return promise;
};

// Default cache key generator (works with Booleans, Strings, Numbers and Dates)
// You will need to create your own key generator if you work with Arrays etc.
ResultsCache.prototype._cacheKeyGenerator = function(args) {
    return Array.prototype.slice.call(arguments).join("|");
};

কিছু (অনুকরণীয় ভারী) গণনা সম্পাদন করতে এই শ্রেণিটি ব্যবহার করার উদাহরণ এখানে রয়েছে:

// The addingMachine will add two numbers
var addingMachine = new ResultsCache(function(a, b, resultHandler) {
    console.log("Performing computation: adding " + a + " and " + b);
    // simulate rather long calculation time by using a 1s timeout
    setTimeout(function() {
        var result = a + b;
        resultHandler(result);
    }, 1000);
});

addingMachine.compute(2, 4).then(function(result) {
    console.log("result: " + result);
});

addingMachine.compute(1, 1).then(function(result) {
    console.log("result: " + result);
});

// cached result will be used
addingMachine.compute(2, 4).then(function(result) {
    console.log("result: " + result);
});

একই অন্তর্নিহিত ক্যাশে অ্যাজাক্স অনুরোধগুলি ক্যাশে করতে ব্যবহৃত হতে পারে:

var ajaxCache = new ResultsCache(function(id, resultHandler) {
    console.log("Performing Ajax request for id '" + id + "'");
    $.getJSON('http://jsfiddle.net/echo/jsonp/?callback=?', {value: id}, function(data) {
        resultHandler(data.value);
    });
});

ajaxCache.compute("anID").then(function(result) {
    console.log("result: " + result);
});

ajaxCache.compute("anotherID").then(function(result) {
    console.log("result: " + result);
});

// cached result will be used
ajaxCache.compute("anID").then(function(result) {
    console.log("result: " + result);
});

আপনি এই জেএসফিডেলে উপরের কোডটি দিয়ে খেলতে পারেন ।


9

1) কলব্যাকের আদেশ প্রাপ্ত কার্যকরকরণ নিশ্চিত করতে এটি ব্যবহার করুন:

var step1 = new Deferred();
var step2 = new Deferred().done(function() { return step1 });
var step3 = new Deferred().done(function() { return step2 });

step1.done(function() { alert("Step 1") });
step2.done(function() { alert("Step 2") });
step3.done(function() { alert("All done") });
//now the 3 alerts will also be fired in order of 1,2,3
//no matter which Deferred gets resolved first.

step2.resolve();
step3.resolve();
step1.resolve();

2) অ্যাপের স্থিতি যাচাই করতে এটি ব্যবহার করুন:

var loggedIn = logUserInNow(); //deferred
var databaseReady = openDatabaseNow(); //deferred

jQuery.when(loggedIn, databaseReady).then(function() {
  //do something
});

2

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

var resizeQueue = new $.Deferred(); //new is optional but it sure is descriptive
resizeQueue.resolve();

function resizeAlgorithm() {
//some resize code here
}

$(window).resize(function() {
    resizeQueue.done(resizeAlgorithm);
});

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


এটি কীভাবে কোনও সিরিয়ালাইজেশন করে? আপনি ইতিমধ্যে কিউ সমাধান resizeQueue.done(resizeAlgorithm)করেছেন ঠিক ঠিক তেমনই resizeAlgorithm। এটা সম্পূর্ণ লজ্জা!
রায়নোস

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

ব্রাউজারে জেএস ইন্টারপ্রেটার একক থ্রেডযুক্ত। আপনার আকার পরিবর্তন অ্যালগোরিদমের ভিতরে কিছু অ্যাসিঙ্ক কোড না থাকলে পুরো ফাংশনটি পরবর্তী কল করার আগেই কাজ শেষ করা উচিত ছিল .done
রায়নস

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

2
আপনার ক্রিয়াকলাপ প্রতি আকারে একবার আরও ফায়ার করে ফায়ারিং প্রতিরোধ করার জন্য আপনি থ্রোটল / ডিবিউন প্লাগইন বেনালম্যান. com/প্রজেক্টস / জ্যাকেই-থ্রটল-ডাবনস-প্লাগিনের মতো কিছু ব্যবহার করবেন না ।
Wheresrhys

2

আপনি এটিকে যে কোনও তৃতীয় পক্ষের লাইব্রেরির সাথে সংহত করতে পারেন যা JQuery ব্যবহার করে।

এরকম একটি লাইব্রেরি হ'ল ব্যাকবোন, যা তাদের পরবর্তী সংস্করণে ডিফার্ডকে আসলে সমর্থন করবে।


2
read more hereজায়গায় ব্যবহার করুন on my blog। এটি একটি ভাল অনুশীলন এবং স্প্যামযুক্ত হওয়ার (দুর্ঘটনাক্রমে) উত্তর থেকে বাঁচাতে পারে। :)
লোকেশ মেহরা

1

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

terminal.exec('command').then(function() {
   terminal.echo('command finished');
});

অথবা

terminal.exec(['command 1', 'command 2', 'command 3']).then(function() {
   terminal.echo('all commands finished');
});

কমান্ডগুলি অ্যাসিঙ্ক কোড চালাতে পারে এবং এক্সিকিউটিভের সাথে ইউজার কোডটি কল করতে হবে। আমার প্রথম এপিআই বিরতি / পুনঃসূচনা কলগুলির জোড় ব্যবহার করে এবং নতুন এপিআইতে আমি ব্যবহারকারীদের প্রত্যাবর্তনের প্রতিশ্রুতি দিলে আমি সেই স্বয়ংক্রিয় কল করি। সুতরাং ব্যবহারকারীর কোডটি কেবল ব্যবহার করতে পারে

return $.get('/some/url');

অথবা

var d = new $.Deferred();
setTimeout(function() {
    d.resolve("Hello Deferred"); // resolve value will be echoed
}, 500);
return d.promise();

আমি এই জাতীয় কোড ব্যবহার করি:

exec: function(command, silent, deferred) {
    var d;
    if ($.isArray(command)) {
        return $.when.apply($, $.map(command, function(command) {
            return self.exec(command, silent);
        }));
    }
    // both commands executed here (resume will call Term::exec)
    if (paused) {
        // delay command multiple time
        d = deferred || new $.Deferred();
        dalyed_commands.push([command, silent, d]);
        return d.promise();
    } else {
        // commands may return promise from user code
        // it will resolve exec promise when user promise
        // is resolved
        var ret = commands(command, silent, true, deferred);
        if (!ret) {
            if (deferred) {
                deferred.resolve(self);
                return deferred.promise();
            } else {
                d = new $.Deferred();
                ret = d.promise();
                ret.resolve();
            }
        }
        return ret;
    }
},

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

এবং কমান্ডের ফাংশনের অংশ (আমি সম্পর্কিত অংশগুলি ছাঁটাই করেছি)

function commands(command, silent, exec, deferred) {

    var position = lines.length-1;
    // Call user interpreter function
    var result = interpreter.interpreter(command, self);
    // user code can return a promise
    if (result != undefined) {
        // new API - auto pause/resume when using promises
        self.pause();
        return $.when(result).then(function(result) {
            // don't echo result if user echo something
            if (result && position === lines.length-1) {
                display_object(result);
            }
            // resolve promise from exec. This will fire
            // code if used terminal::exec('command').then
            if (deferred) {
                deferred.resolve();
            }
            self.resume();
        });
    }
    // this is old API
    // if command call pause - wait until resume
    if (paused) {
        self.bind('resume.command', function() {
            // exec with resume/pause in user code
            if (deferred) {
                deferred.resolve();
            }
            self.unbind('resume.command');
        });
    } else {
        // this should not happen
        if (deferred) {
            deferred.resolve();
        }
    }
}

1

কাহিনী দ্বারা উত্তর কার্যকর হবে না, কারণ এটি প্রতিক্রিয়া ডেটা ক্যাশে। এটি jqXHR কে ক্যাশে করা উচিত যা এটিও একটি প্রতিশ্রুতি। এখানে সঠিক কোডটি রয়েছে:

var cache = {};

function getData( val ){

    // return either the cached value or an
    // jqXHR object (which contains a promise)
    return cache[ val ] || $.ajax('/foo/', {
        data: { value: val },
        dataType: 'json',
        success: function(data, textStatus, jqXHR){
            cache[ val ] = jqXHR;
        }
    });
}

getData('foo').then(function(resp){
    // do something with the response, which may
    // or may not have been retreived using an
    // XHR request.
});

জুলিয়ান ডি দ্বারা উত্তর সঠিকভাবে কাজ করবে এবং এটি একটি আরও ভাল সমাধান।

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