আপনি কীভাবে jQuery ডিফার্ডস এর অ্যারে দিয়ে কাজ করবেন?


132

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

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

আমি তখন সমস্ত স্কিমার জন্য আনয়নটি দেখতে পাচ্ছি, সুতরাং প্রতিটি each .ajax () কল কাজ করে। ফেচশেমাস () প্রকৃতপক্ষে প্রতিশ্রুতির একটি অ্যারে প্রদান করে।

যাইহোক, এই চূড়ান্ত যখন () ধারাটি কখনই জ্বলে না এবং কনসোলে কখনই "ডোন" শব্দটি উপস্থিত হয় না। Jquery-1.5 এর উত্স কোডটি বোঝা যাচ্ছে যে "নাল" $। কাছে যাওয়ার জন্য একটি অবজেক্ট হিসাবে গ্রহণযোগ্য w মধ্যে পাস

এটি Futures.js ব্যবহার করে কাজ করেছে। এটি পছন্দ না হলে কীভাবে jQuery ডিফার্ডগুলির একটি অ্যারে পরিচালনা করা উচিত?

    var fetch_schemas, fetch_root;

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

    fetch_root = function() {
        return $.ajax({
            url: BASE_URL,
            data: {},
            contentType: "application/json; charset=utf-8",
            dataType: "json"
        });
    };

    $.when(fetch_root()).then(function(data) {
        var promises = fetch_schemas(data.schema_urls);
        $.when.apply(null, promises).then(function(schemas) {
            console.log("DONE", this, schemas);
        });
    });

আমার প্রায় একটি অভিন্ন সমস্যা রয়েছে, তবে "ডোন" প্রিন্ট হওয়ার আগে, ফেচ_নে প্রতিটি এজাক্স ক্যোয়ারির জন্য "সাফল্য" পদ্ধতিটি চালিত করা দরকার except আপনি কীভাবে এটি করতে যাবেন? আমি "ফেচ_োন" এর পরে। পাইপ ব্যবহার করার চেষ্টা করেছি, তবে এটি কাজ করে বলে মনে হচ্ছে না।
কেমব্রিজমাইক

উত্তর:


198

তুমি খুঁজছ

$.when.apply($, promises).then(function(schemas) {
     console.log("DONE", this, schemas);
}, function(e) {
     console.log("My ajax failed");
});

এটিও কাজ করবে (কাজের কিছু মূল্যের জন্য, এটি ভাঙ্গা এজাক্স ঠিক করবে না):

$.when.apply($, promises).done(function() { ... }).fail(function() { ... });` 

আপনি এর $পরিবর্তে পাস করতে চাইবেন nullযাতে thisঅভ্যন্তরটি $.whenবোঝায় jQuery। উত্সটির সাথে এটি বিবেচনা করা উচিত নয় তবে উত্তীর্ণ হওয়ার পরে এটি আরও ভাল null

আপনার সমস্ত aj .AXX এর সাথে প্রতিস্থাপন করে $.whenএবং নমুনাটি কাজ করে

সুতরাং এটি হয় আপনার এজাক্স অনুরোধে সমস্যা বা অ্যারে আপনার ফেচ_শেমাসের পাসিংয়ের ক্ষেত্রে।


ধন্যবাদ. এই সিনট্যাক্সটি কীভাবে সম্পন্ন ()। ব্যর্থ () থেকে আলাদা?
এল্ফ স্টার্নবার্গ

2
@ দ্বিতীয় স্টার্নবার্গ, .then(a,b) === .done(a).fail(b)এটি একটি অলস শর্টহ্যান্ড। আপনি চাইলে কল .done(a).fail(b)করতে পারেন
রায়নোস

1
ওহ, এবং $ .হেন.অ্যাপ্লি ($, ...) এবং $। যখন। অ্যাপ্লিকেশন (নাল, ...) এর ব্যবহার অপ্রাসঙ্গিক বলে মনে হচ্ছে। jQuery নিজেই একটি প্রতিশ্রুতি () পদ্ধতি নেই, তাই এটি অভ্যন্তরীণভাবে উত্পন্ন ডিফার্ড অবজেক্ট (jQuery 1.5, লাইন 943) এর পক্ষে অগ্রাহ্য হয়।
এল্ফ স্টারনবার্গ

1
@ এল্ফস্টারনবার্গ এটি প্রকৃতপক্ষে অপ্রাসঙ্গিক, তবে পাঠযোগ্যতার জন্য আমার আর দ্বিতীয় নজরে নেওয়ার দরকার নেই $.when.apply($, ...nullআমাকে যেতে বাধ্য "অপেক্ষার, কি?"। এটি স্টাইল এবং কোডিং অনুশীলনের বিষয়। আমাকে উত্সটি পড়তে হয়েছিল তা নিশ্চিত thisকরতে jQuery.when এর ভিতরে কোনও নাল রেফারেন্স ফেলবে না!
রায়নোস

7
নাল ব্যবহার আমাকে ভাবতে বাধ্য করে যে 'ঠিক আছে, এটি এক প্রকারের কাজ' (যা এটি), তবে যদি used ব্যবহৃত হয় তবে আমার মনোযোগ ডাব্লুটিএফ সম্পর্কে চিন্তাভাবনার দিকে ঝুঁকানো হবে for এর জন্য।
দানিয়াল আয়তেকিন

53

উপরে বর্ণিত (ধন্যবাদ!) স্থগিতের resolve()পদ্ধতিতে প্রদত্ত বস্তুগুলি ফিরিয়ে আনার সমস্যাটিকে সঠিকভাবে সমাধান করে না কারণ jQuery একটি অ্যারে নয়, পৃথক প্যারামিটারগুলির সাথে কল done()এবং fail()কলব্যাকগুলি কল করে । তার মানে হল যে argumentsসিফরও-অ্যারে ডিফার্ডের অ্যারে দ্বারা ফিরিয়ে নেওয়া সমস্ত সমাধান করা / প্রত্যাখ্যানিত অবজেক্টগুলি পেতে আমাদের ছদ্ম-অ্যারে ব্যবহার করতে হবে:

$.when.apply($, promises).then(function() {
     var schemas=arguments; // The array of resolved objects as a pseudo-array
     ...
};

যেহেতু আমরা স্থগিতের একটি অ্যারে পেরিয়েছি, ফলাফলের অ্যারে ফিরে পাওয়া ভাল লাগবে। সিউডো-অ্যারের পরিবর্তে একটি প্রকৃত অ্যারে ফিরে পাওয়া ভাল লাগবে যাতে আমরা এর মতো পদ্ধতি ব্যবহার করতে পারি Array.sort()

এখানে.জেএস এর when.all()পদ্ধতি দ্বারা অনুপ্রাণিত একটি সমাধান যা এই সমস্যার সমাধান করে:

// Put somewhere in your scripting environment
if (jQuery.when.all===undefined) {
    jQuery.when.all = function(deferreds) {
        var deferred = new jQuery.Deferred();
        $.when.apply(jQuery, deferreds).then(
            function() {
                deferred.resolve(Array.prototype.slice.call(arguments));
            },
            function() {
                deferred.fail(Array.prototype.slice.call(arguments));
            });

        return deferred;
    }
}

এখন আপনি কেবল স্থগিত / প্রতিশ্রুতিগুলির একটি অ্যারে পাস করতে পারেন এবং আপনার কলব্যাকে সমাধান / প্রত্যাখ্যাত বস্তুর একটি অ্যারে ফিরে পেতে পারেন:

$.when.all(promises).then(function(schemas) {
     console.log("DONE", this, schemas); // 'schemas' is now an array
}, function(e) {
     console.log("My ajax failed");
});

@ ক্রিস্পিপড্যাক - আপনি কি জানেন যে আপনি যদি 100% নিশ্চিত হতে পারেন যে "স্কিমাস" এর মধ্যে অ্যারে উপাদানগুলির ক্রম তখন () তখন "অ্যাসেক্স" কল হিসাবে অজ্যাক্স কল হিসাবে সর্বদা একই ক্রমে থাকবে ()?
নেটপোটিটিকা

6
এটিকে কেবল বিল্ট-ইন jQuery করা উচিত, তবে - jQuery টিমটি অনুরোধটি বেশ কয়েকবার প্রত্যাখ্যান করেছে। এদিকে, লোকেরা এখানে প্রশ্ন জিজ্ঞাসা করে এবং jQuery এর বিপরীতে অনুরূপ টিকিট খোলার চেষ্টা করে এবং আমরা সর্বত্র একটি ইউজারল্যান্ড বাস্তবায়নের সাথে শেষ হয় এবং / অথবা অদ্ভুত কলগুলি apply()... ফিগারে যান।
mindplay.dk

এই সমাধানের জন্য ধন্যবাদ! একটি (বা আরও) ব্যর্থ হলে সফল আইটেমগুলি পাওয়ার কী কী উপায় আছে?
doktoreas

ভাল আপনি এখানে যা করেছেন তা হ'ল argumentsনিজস্ব পদ্ধতিতে ম্যানিপুলেশন। পুনরায় ব্যবহারের জন্য দুর্দান্ত তবে মোকাবেলা করার "কদর্যতা" argumentsvar schemas=Array.prototype.slice.call(arguments);)
সম্বোধন

2
@ ক্রিস্পিপডাক, deferred.fail(...)পড়া উচিত নয় deferred.reject(...)?
বব এস

19

আপনি যদি জাভাস্ক্রিপ্টের ES6 সংস্করণ ব্যবহার করছেন তবে একটি স্প্রেড অপারেটর (...) রয়েছে যা বস্তুর অ্যারেটিকে কমা দ্বারা পৃথক যুক্তিগুলিতে রূপান্তর করে।

$.when(...promises).then(function() {
 var schemas=arguments; 
};

ES6 স্প্রেড অপারেটর সম্পর্কে আরও https://developer.mozilla.org/en-US/docs/Web/ জাভা স্ক্রিপ্ট / রেফারেন্স / অপারেটর / স্প্রেড_অপ্রেটর এখানে পান


1
হা. যদিও আমরা যারা Coffeescript ব্যবহার করছি বা এর বংশধরদের / অনুকরণকারীদের মধ্যে কিছুক্ষণের জন্য সেই অপারেটরের অ্যাক্সেস রয়েছে।
এল্ফ স্টার্নবার্গ

0

এই কোড সহ যখন প্রসারিত:

var rawWhen = $.when
$.when = function(promise) {
    if ($.isArray(promise)) {
        var dfd = new jQuery.Deferred()
        rawWhen.apply($, promise).done(function() {
            dfd.resolve(Array.prototype.slice.call(arguments))
        }).fail(function() {
            dfd.reject(Array.prototype.slice.call(arguments))
        })
        return dfd.promise()
    } else {
        return rawWhen.apply($, arguments)
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.