সাফল্য: / ব্যর্থতা: ব্লক বনাম সমাপ্তি: ব্লক


23

আমি অবজেক্টিভ-সি-তে ব্লকের জন্য দুটি সাধারণ নিদর্শন দেখতে পাচ্ছি। একটি সাফল্যের জুড়ি: / ব্যর্থতা: ব্লক, অন্যটি একক সমাপ্তি: ব্লক।

উদাহরণস্বরূপ, আসুন আমি বলি যে আমার কাছে একটি টাস্ক রয়েছে যা কোনও বস্তুকে অবিচ্ছিন্নভাবে ফিরিয়ে দেবে এবং সেই কাজটি ব্যর্থ হতে পারে। প্রথম প্যাটার্নটি হ'ল -taskWithSuccess:(void (^)(id object))success failure:(void (^)(NSError *error))failure। দ্বিতীয় প্যাটার্নটি হ'ল -taskWithCompletion:(void (^)(id object, NSError *error))completion

সাফল্য ব্যর্থতা:

[target taskWithSuccess:^(id object) {
    // W00t! I've got my object
} failure:^(NSError *error) {
    // Oh noes! report the failure.
}];

সম্পূর্ণকরণ:

[target taskWithCompletion:^(id object, NSError *error) {
    if (object) {
        // W00t! I've got my object
    } else {
        // Oh noes! report the failure.
    }
}];

পছন্দের প্যাটার্নটি কোনটি? শক্তি এবং দুর্বলতাগুলি কী কী? আপনি কখন অন্যটির উপরে ব্যবহার করবেন?


আমি নিশ্চিত যে অবজেক্টিভ-সি-তে থ্রোক / ক্যাচ ব্যতিক্রমী হ্যান্ডেলিং রয়েছে, আপনি কি এটি ব্যবহার করতে পারবেন না এমন কোনও কারণ আছে?
হতাশ

হয় এই অনুমতি চেইন অ্যাসিঙ্ক কলগুলির মধ্যে যে কোনওটি ব্যতিক্রম আপনাকে দেয় না।
ফ্র্যাঙ্ক শিয়েরার 23'13

5
@FrustratedWithFormsDesigner: stackoverflow.com/a/3678556/2289 - কথ্য objc প্রবাহ নিয়ন্ত্রণের জন্য ব্যবহার করে দেখুন / ধরা ব্যবহার করে না।
পিঁপড়ে

1
দয়া করে আপনার উত্তরটি প্রশ্ন থেকে উত্তরের দিকে নিয়ে যাওয়া বিবেচনা করুন ... সর্বোপরি, এটি একটি উত্তর (এবং আপনি নিজের প্রশ্নের উত্তর দিতে পারেন)।

1
অবশেষে আমি পিয়ারের চাপে আটকালাম এবং আমার উত্তরটি একটি সত্য উত্তরে সরিয়ে নিয়েছি।
জেফারি থমাস 11

উত্তর:


8

সমাপ্তি কলব্যাক (সাফল্যের বিপরীতে / ব্যর্থতার জোড়) আরও জেনেরিক। যদি আপনাকে রিটার্নের স্থিতি নিয়ে কাজ করার আগে কিছু প্রসঙ্গ প্রস্তুত করতে হয় তবে আপনি "যদি (অবজেক্ট)" ধারাটির ঠিক আগে এটি করতে পারেন। সাফল্য / ব্যর্থতার ক্ষেত্রে আপনাকে এই কোডটি নকল করতে হবে। এটি অবশ্যই কলব্যাক শব্দার্থবিজ্ঞানের উপর নির্ভর করে।


মূল প্রশ্নে মন্তব্য করা যায় না ... ব্যতিক্রমগুলি উদ্দেশ্য-সি (ভাল, কোকো) এ বৈধ প্রবাহ নিয়ন্ত্রণ নয় এবং এর মতো ব্যবহার করা উচিত নয়। ছুঁড়ে দেওয়া ব্যতিক্রম কেবল কৃত্রিমভাবে শেষ করতে ক্যাচ করা উচিত।

হ্যাঁ, আমি এটি দেখতে পারি। যদি -task…অবজেক্টটি ফেরত দিতে পারত তবে অবজেক্টটি সঠিক অবস্থায় না থাকে তবে সাফল্যের শর্তে আপনার এখনও ত্রুটি পরিচালনা করতে হবে।
জেফারি টমাস

হ্যাঁ, এবং যদি ব্লকটি স্থানে না থাকে তবে এটি আপনার নিয়ামকের পক্ষে যুক্তি হিসাবে দেওয়া হয়, আপনাকে প্রায় দুটি ব্লক টস করতে হবে। কলব্যাক অনেক স্তর দিয়ে যাওয়ার প্রয়োজন হলে এটি বিরক্তিকর হতে পারে। যদিও আপনি সর্বদা এটি আবার বিভক্ত / রচনা করতে পারেন, যদিও।

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

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

8

আমি বলব, এপিআই একটি সম্পূর্ণতা হ্যান্ডলার সরবরাহ করে বা সাফল্য / ব্যর্থতা ব্লকগুলির জুড়ি দেয় কিনা তা মূলত ব্যক্তিগত পছন্দের বিষয়।

উভয় পদ্ধতিরই উপকারিতা এবং বোধ রয়েছে, যদিও কেবল সামান্য পার্থক্য রয়েছে।

আরও আরও বৈকল্পিক রয়েছে তা বিবেচনা করুন, উদাহরণস্বরূপ যেখানে এক সম্পূর্ণ হওয়ার হ্যান্ডলারটির কেবলমাত্র পরিণতি বা কোনও সম্ভাব্য ত্রুটির সমন্বয়ে কেবলমাত্র একটি প্যারামিটার থাকতে পারে :

typedef void (^completion_t)(id result);

- (void) taskWithCompletion:(completion_t)completionHandler;

[self taskWithCompletion:^(id result){
    if ([result isKindOfError:[NSError class]) {
        NSLog(@"Error: %@", result);
    }
    else {
        ...
    }
}]; 

এই স্বাক্ষরটির উদ্দেশ্য হ'ল একটি সমাপ্তি হ্যান্ডলারটি অন্য এপিআইতে সাধারণভাবে ব্যবহার করা যায়।

উদাহরণস্বরূপ এনএসএর্রের জন্য বিভাগে একটি পদ্ধতি রয়েছে forEachApplyTask:completion:যা ক্রমান্বয়ে প্রতিটি বস্তুর জন্য একটি কার্য ডাকে এবং লুপটি ভেঙে দেয় যদি ত্রুটি ঘটেছিল। যেহেতু এই পদ্ধতিটি নিজেও অবিচ্ছিন্ন, তাই এটির একটি সমাপ্তি হ্যান্ডলারও রয়েছে:

typedef void (^completion_t)(id result);
typedef void (^task_t)(id input, completion_t);
- (void) forEachApplyTask:(task_t)task completion:(completion_t);

প্রকৃতপক্ষে, completion_tউপরে বর্ণিত হিসাবে সাধারণভাবে যথেষ্ট এবং সমস্ত পরিস্থিতিতে পরিচালনা করতে যথেষ্ট।

তবে কল-সাইটে এর সমাপ্তির বিজ্ঞপ্তিটি সংকেত দেওয়ার জন্য একটি অ্যাসিঙ্ক্রোনাস টাস্কের অন্যান্য উপায় রয়েছে:

অঙ্গীকার

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

প্রাথমিকভাবে, একটি প্রতিশ্রুতি "মুলতুবি" অবস্থায় রয়েছে। অর্থাৎ এটির "মান" এখনও মূল্যায়ন করা হয়নি এবং এখনও পাওয়া যায় নি।

অবজেক্টিভ-সি-তে, প্রতিশ্রুতিবদ্ধ হ'ল একটি সাধারণ অবজেক্ট যা নীচে প্রদর্শিত হিসাবে অ্যাসিক্রোনাস পদ্ধতি থেকে ফিরে আসবে:

- (Promise*) doSomethingAsync;

! প্রতিশ্রুতির প্রাথমিক অবস্থা "মুলতুবি"।

ইতিমধ্যে, অ্যাসিক্রোনাস কাজগুলি তার ফলাফলটি মূল্যায়ন করতে শুরু করে।

আরও মনে রাখবেন, কোনও সমাপ্তি হ্যান্ডলার নেই। পরিবর্তে, প্রতিশ্রুতি আরও শক্তিশালী উপায় সরবরাহ করবে যেখানে কল-সাইট অ্যাসিনক্রোনাস টাস্কের পরিণামটি পেতে পারে, যা আমরা শীঘ্রই দেখতে পাব।

অ্যাসিক্রোনাস টাস্ক, যা প্রতিশ্রুতি বস্তু তৈরি করেছিল, শেষ পর্যন্ত এর প্রতিশ্রুতি "সংকল্প" করা আবশ্যক। এর অর্থ, যেহেতু কোনও কাজ সফল হয় বা ব্যর্থ হতে পারে, তাই এটি মূল্যায়নকৃত ফলাফলটি পাস করার একটি প্রতিশ্রুতি "পূরণ" করতে হবে, বা ব্যর্থতার কারণকে নির্দেশ করে একটি ত্রুটি পাস করার প্রতিশ্রুতি "প্রত্যাখ্যান" করা আবশ্যক।

! একটি কাজ শেষ পর্যন্ত তার প্রতিশ্রুতি সমাধান করতে হবে।

যখন কোনও প্রতিশ্রুতি সমাধান করা হয়, তখন এর মান সহ এটি আর রাষ্ট্রের পরিবর্তন করতে পারে না।

! একটি প্রতিশ্রুতি কেবল একবার সমাধান করা যেতে পারে ।

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

একটি প্রতিশ্রুতি পারেন করার জন্য একটি সমলয় অথবা একটি অ্যাসিঙ্ক্রোনাস শৈলী যেখানে বিশালাকার বাস্তবায়িত করা যাবে ব্লক যথাক্রমে অ ব্লক শব্দার্থবিদ্যা।

প্রতিশ্রুতির মান পুনরুদ্ধার করার জন্য একটি সিঙ্ক্রোনাস স্টাইলে, একটি কল-সাইট এমন একটি পদ্ধতি ব্যবহার করবে যা বর্তমান থ্রেডকে অ্যাসিঙ্ক্রোনাস টাস্ক দ্বারা প্রতিশ্রুতি সমাধান না করা এবং পরিণাম প্রাপ্ত ফলাফল প্রাপ্ত হওয়া অবধি অবরুদ্ধ করবে ।

অ্যাসিঙ্ক্রোনাস স্টাইলে, কল-সাইট কলব্যাকগুলি বা হ্যান্ডলার ব্লকগুলি নিবন্ধভুক্ত করবে যা প্রতিশ্রুতি সমাধানের সাথে সাথে কল হয়ে যায়।

এটি প্রমাণিত হয়েছে যে সিঙ্ক্রোনাস স্টাইলে বেশ কয়েকটি উল্লেখযোগ্য অসুবিধা রয়েছে যা কার্যকরভাবে অ্যাসিঙ্ক্রোনাস টাস্কগুলির গুণাবলীকে পরাভূত করে। স্ট্যান্ডার্ড সি ++ 11 লাইবটিতে বর্তমানে "ফিউচার" এর ত্রুটিযুক্ত বাস্তবায়ন সম্পর্কে একটি আকর্ষণীয় নিবন্ধটি এখানে পড়তে পারেন: ভাঙা প্রতিশ্রুতি – C ++ 0x ফিউচার

কীভাবে, উদ্দেশ্য-সি-তে, কোনও কল-সাইট ফলাফল অর্জন করবে?

ভাল, কয়েকটি উদাহরণ প্রদর্শন করা ভাল। এখানে দুটি পাঠাগার রয়েছে যা একটি প্রতিশ্রুতি বাস্তবায়ন করে (নীচের লিঙ্কগুলি দেখুন)।

তবে, পরবর্তী কোড স্নিপেটের জন্য, আমি গিটহাব আরএক্সপ্রোমিতে উপলব্ধ একটি প্রতিশ্রুতি পাঠাগারটির একটি বিশেষ প্রয়োগ ব্যবহার করব । আমি আরএক্সপ্রোমাইজের লেখক।

অন্যান্য বাস্তবায়নের অনুরূপ এপিআই থাকতে পারে তবে সিনট্যাক্সে ছোট এবং সম্ভবত সূক্ষ্ম পার্থক্য থাকতে পারে। আরএক্সপ্রাইম হ'ল প্রতিশ্রুতি / এ + নির্দিষ্টকরণের একটি উদ্দেশ্য-সি সংস্করণ যা জাভাস্ক্রিপ্টে প্রতিশ্রুতিগুলির মজবুত এবং আন্তঃব্যবহারযোগ্য প্রয়োগের জন্য একটি মুক্ত মান নির্ধারণ করে।

নীচে তালিকাভুক্ত সমস্ত প্রতিশ্রুতি পাঠাগারগুলি অ্যাসিঙ্ক্রোনাস শৈলী বাস্তবায়ন করে।

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

একটি কল-সাইট হ্যান্ডলারের "নিবন্ধকরণ" এর মাধ্যমে অ্যাসিনক্রোনাস টাস্কের শেষ ফলাফল প্রাপ্ত করে। "প্রতিশ্রুতি / এ + নির্দিষ্টকরণ" পদ্ধতিটি সংজ্ঞায়িত করে then

পদ্ধতি then

আরএক্সপ্রাইজ সহ এটি নীচের মত দেখাচ্ছে:

promise.then(successHandler, errorHandler);

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

! thenচূড়ান্ত ফলাফল পেতে এবং একটি সাফল্য বা একটি ত্রুটি হ্যান্ডলার সংজ্ঞায়িত করতে ব্যবহৃত হয়।

আরএক্সপ্রাইমে হ্যান্ডলার ব্লকের নীচে স্বাক্ষর রয়েছে:

typedef id (^success_handler_t)(id result);
typedef id (^error_handler_t)(NSError* error);

সাফল্য_হ্যান্ডলারের একটি প্যারামিটার ফলাফল রয়েছে যা স্পষ্টতই অ্যাসিনক্রোনাস টাস্কের পরিণাম। তেমনি, ত্রুটি- হ্যান্ডলারের একটি প্যারামিটার ত্রুটি থাকে যা এটি ব্যর্থ হওয়ার পরে অ্যাসিক্রোনাস টাস্ক দ্বারা রিপোর্ট করা ত্রুটি।

উভয় ব্লকের একটি ফেরতের মান রয়েছে। এই রিটার্নের মান কী, তা শিগগিরই পরিষ্কার হয়ে যাবে।

আরএক্সপ্রোমিতে, thenএমন একটি সম্পত্তি যা একটি ব্লক দেয়। এই ব্লকের দুটি পরামিতি রয়েছে, সাফল্য হ্যান্ডলার ব্লক এবং ত্রুটি হ্যান্ডলার ব্লক। হ্যান্ডলারগুলি অবশ্যই কল-সাইট দ্বারা সংজ্ঞায়িত করা উচিত।

! হ্যান্ডলারগুলি অবশ্যই কল-সাইট দ্বারা সংজ্ঞায়িত করা উচিত।

সুতরাং, অভিব্যক্তি promise.then(success_handler, error_handler);একটি সংক্ষিপ্ত রূপ

then_block_t block promise.then;
block(success_handler, error_handler);

আমরা আরও বেশি সংক্ষিপ্ত কোড লিখতে পারি:

doSomethingAsync
.then(^id(id result){
    
    return @“OK”;
}, nil);

কোডটিতে লেখা আছে: "doSomethingAsync কার্যকর করুন, যখন এটি সফল হয়, তারপরে সাফল্য হ্যান্ডলার কার্যকর করুন"।

এখানে, ত্রুটি হ্যান্ডলারটি nilযার অর্থ, কোনও ত্রুটির ক্ষেত্রে, এটি এই প্রতিশ্রুতিতে পরিচালিত হবে না।

আর একটি গুরুত্বপূর্ণ বিষয় হ'ল সম্পত্তি থেকে ফিরে আসা ব্লকটি কল করা thenএকটি প্রতিশ্রুতি ফিরিয়ে দেবে:

! then(...)প্রতিশ্রুতি দেয়

সম্পত্তি থেকে ফিরে আসা ব্লকটি কল করার সময় then, "রিসিভার" একটি নতুন প্রতিশ্রুতি দেয়, সন্তানের প্রতিশ্রুতি। গ্রহীতা পিতামাতার প্রতিশ্রুতি হয়ে ওঠে ।

RXPromise* rootPromise = asyncA();
RXPromise* childPromise = rootPromise.then(successHandler, nil);
assert(childPromise.parent == rootPromise);

ওটার মানে কি?

ঠিক আছে, এর কারণে আমরা অ্যাসিঙ্ক্রোনাস কাজগুলিকে কার্যকরভাবে ক্রমান্বয়ে কার্যকর করতে পারি "চেইন" করতে পারি।

তদ্ব্যতীত, উভয়ই হ্যান্ডলারের ফেরতের মান প্রত্যাশিত প্রতিশ্রুতির "মান" হয়ে উঠবে। সুতরাং, যদি কাজটি শেষ ফলাফল @ "ঠিক আছে" দিয়ে সফল হয় তবে প্রত্যাবর্তিত প্রতিশ্রুতি "" ঠিক আছে "মান সহ" সমাধান "হবে (এটি" পরিপূর্ণ ") হবে:

RXPromise* returnedPromise = asyncA().then(^id(id result){
    return @"OK";
}, nil);

...
assert([[returnedPromise get] isEqualToString:@"OK"]);

তেমনিভাবে, যখন অ্যাসিক্রোনাস টাস্ক ব্যর্থ হয়, প্রত্যাবর্তিত প্রতিশ্রুতি একটি ত্রুটি সহ সমাধান করা হবে (এটি "প্রত্যাখ্যানিত")।

RXPromise* returnedPromise = asyncA().then(nil, ^id(NSError* error){
    return error;
});

...
assert([[returnedPromise get] isKindOfClass:[NSError class]]);

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

RXPromise* returnedPromise = asyncA().then(^id(id result){
    return asyncB(result);
}, nil);

! একটি হ্যান্ডলার ব্লকের রিটার্ন মান শিশুর প্রতিশ্রুতির মান হয়ে যায়।

যদি কোনও সন্তানের প্রতিশ্রুতি না থাকে তবে রিটার্ন মানটির কোনও প্রভাব নেই।

আরও জটিল উদাহরণ:

এখানে, আমরা চালানো asyncTaskA, asyncTaskB, asyncTaskCএবং asyncTaskD ক্রমানুসারে - এবং প্রতিটি পরবর্তী কাজের ইনপুট হিসাবে পূর্ববর্তী কাজের ফল লাগে:

asyncTaskA()
.then(^id(id result){
    return asyncTaskB(result);
}, nil)
.then(^id(id result){
    return asyncTaskC(result);
}, nil)
.then(^id(id result){
    return asyncTaskD(result);
}, nil)
.then(^id(id result){
    // handle result
    return nil;
}, nil);

এই জাতীয় "চেইন" কে "ধারাবাহিকতা" বলা হয়।

ত্রুটি পরিচালনা

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

asyncTaskA()
.then(^id(id result){
    return asyncTaskB(result);
}, nil)
.then(^id(id result){
    return asyncTaskC(result);
}, nil)
.then(^id(id result){
    return asyncTaskD(result);
}, nil)
.then(^id(id result){
    // handle result
    return nil;
}, nil);
.then(nil, ^id(NSError*error) {
    NSLog(@“”Error: %@“, error);
    return nil;
});

এটি ব্যতিক্রম হ্যান্ডলিংয়ের সাথে সম্ভবত আরও পরিচিত সিনক্রোনাস স্টাইলের অনুরূপ:

try {
    id a = A();
    id b = B(a);
    id c = C(b);
    id d = D(c);
    // handle d
}
catch (NSError* error) {
    NSLog(@“”Error: %@“, error);
}

প্রতিশ্রুতি সাধারণভাবে অন্যান্য দরকারী বৈশিষ্ট্য রয়েছে:

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

আরএক্সপ্রোমিসে আরও বেশ কয়েকটি কার্যকর কার্যকরী বৈশিষ্ট্য রয়েছে, প্রতিশ্রুতি / এ + নির্দিষ্টকরণের প্রয়োজন হয় না। একটি হ'ল "বাতিলকরণ"।

দেখা গেল যে "বাতিলকরণ" একটি অমূল্য এবং গুরুত্বপূর্ণ বৈশিষ্ট্য। উদাহরণস্বরূপ, কোনও প্রতিশ্রুতির রেফারেন্স সহ একটি কল-সাইট এটি cancelবার্তাটি প্রেরণ করতে পারে যাতে এটি শেষের ফলাফলের জন্য আর আগ্রহী না।

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

আরএক্সপ্রাইমে, একটি বাতিল বার্তা কেবলমাত্র তার পিতামাতার কাছ থেকে তার বাচ্চাদের কাছে পাঠানো হবে, তবে তদ্বিপরীত নয়। এটি, একটি "মূল" প্রতিশ্রুতি সমস্ত বাচ্চার প্রতিশ্রুতি বাতিল করে দেবে। তবে সন্তানের প্রতিশ্রুতি কেবল সেই "শাখা" বাতিল করবে যেখানে এটি পিতামাতা। যদি কোনও প্রতিশ্রুতি ইতিমধ্যে সমাধান হয়ে যায় তবে বাতিল বার্তাটি বাচ্চাদের কাছেও পাঠানো হবে।

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

এখানে গিটহাবের উপর পাওয়া উদ্দেশ্য-সি-র প্রতিশ্রুতির আরও কয়েকটি বাস্তবায়ন রয়েছে:

https://github.com/Schoonology/aplus-objc
https://github.com/affablebloke/deferred-objective-c
https://github.com/bww/FutureKit
https://github.com/jkubicek/JKPromises
https://github.com/Strilanc/ObjC- CollapsingFutures
https://github.com/b52/OMPromise
https://github.com/mproberts/objc-promise
https://github.com/klaaspieter/Promise
https: //github.com/jameswomack/Promise
https://github.com/nilfs/promise-objc
https://github.com/mxcl/PromiseKit
https://github.com/apleshkov/promises-aplus
https: // github.com/KptainO/Rebelle

এবং আমার নিজস্ব বাস্তবায়ন: আরএক্সপ্রোমাইজ

এই তালিকাটি সম্ভবত সম্পূর্ণ নয়!

আপনার প্রকল্পের জন্য কোনও তৃতীয় গ্রন্থাগার চয়ন করার সময়, দয়া করে লাইব্রেরির প্রয়োগটি নীচে তালিকাভুক্ত পূর্বশর্তগুলি অনুসরণ করে কিনা তা সাবধানতার সাথে পরীক্ষা করে দেখুন:

  • একটি নির্ভরযোগ্য প্রতিশ্রুতি গ্রন্থাগার থ্রেড নিরাপদ হবে!

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

  • হ্যান্ডেলার বলে গন্য হবে অ্যাসিঙ্ক্রোনাস যা কল-সাইট থেকে সম্মান! সর্বদা, এবং যাই হোক না কেন!

    অ্যাসিঙ্ক্রোনাস ফাংশনগুলি গ্রহণ করার সময় যে কোনও শালীন বাস্তবায়নও খুব কঠোর প্যাটার্ন অনুসরণ করা উচিত। অনেক বাস্তবায়নকারী কেসটিকে "অনুকূলিতকরণ" করতে ঝোঁকেন, যেখানে হ্যান্ডলারটি নিবন্ধিত হবে যখন প্রতিশ্রুতি ইতিমধ্যে সমাধান হয়ে গেছে তখন একটি হ্যান্ডলার সিঙ্ক্রোনসিভভাবে ডাকা হবে। এটি সব ধরণের সমস্যার কারণ হতে পারে। জালগো মুক্তি দিবেন না দেখুন !

  • কোনও প্রতিশ্রুতি বাতিল করার ব্যবস্থাও থাকতে হবে।

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


1
এটি এখন পর্যন্ত দীর্ঘতম উত্তর না দেওয়ার জন্য পুরষ্কার পায়। তবে চেষ্টা করার জন্য একটি :-)
ট্র্যাভেলিং ম্যান

3

আমি বুঝতে পারি এটি একটি পুরানো প্রশ্ন তবে আমার উত্তরটি দিতে হবে কারণ আমার উত্তর অন্যদের চেয়ে আলাদা।

যাঁরা বলেন এটি ব্যক্তিগত পছন্দের বিষয়, তাদের সাথে আমার একমত হতে হবে না। একে অপরের চেয়ে বেশি পছন্দ করার একটা ভাল, যৌক্তিক, কারণ আছে ...

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

পৃথক সাফল্য এবং ব্যর্থতা ব্লক থাকা আপনার কোডটি স্থিতিকরূপে যাচাইযোগ্য করে তোলে।


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


1

আমি সন্দেহ করি এটি ব্যক্তিগত পছন্দ হিসাবে শেষ হতে চলেছে ...

তবে আমি পৃথক সাফল্য / ব্যর্থতা ব্লকগুলি পছন্দ করি। আমি সাফল্য / ব্যর্থতার যুক্তি আলাদা করতে পছন্দ করি। যদি আপনার সাফল্য / ব্যর্থতা বাসা বেঁধে দেওয়া থাকে, তবে আপনি এমন কিছু দিয়ে শেষ করতেন যা আরও পাঠযোগ্য হবে (আমার মতে অন্তত)।

এই জাতীয় নীড়ের তুলনামূলকভাবে চরম উদাহরণ হিসাবে, এখানে কিছু রুবি এই প্যাটার্নটি দেখায় showing


1
আমি উভয়ের নেস্টেড চেইন দেখেছি। আমি মনে করি তারা উভয়কে ভয়ঙ্কর দেখাচ্ছে তবে এটি আমার ব্যক্তিগত মতামত।
জেফারি টমাস

1
তবে কীভাবে আপনি অ্যাসিঙ্ক কলগুলি চেইন করতে পারেন?
ফ্র্যাঙ্ক শায়ারার

আমি মানুষকে চিনি না ... জানি না। আমি যে কারণে জিজ্ঞাসা করছি তার একটি অংশ হ'ল আমার অ্যাসিঙ্ক কোডটি কেমন লাগে তা আমি পছন্দ করি না।
জেফারি থমাস

অবশ্যই। আপনি আপনার কোডটি ধারাবাহিকতা-পাসিং স্টাইলে লিখেছেন, যা মারাত্মক অবাক হওয়ার মতো নয়। (হাস্কেলের ঠিক এই কারণে এটির স্বীকৃতি রয়েছে: আপনাকে সম্ভবত সরাসরি স্টাইলে লিখতে দেওয়া))
এটির স্বীকৃতি রয়েছে

আপনি এই ওবিজিতে বাস্তবায়নের প্রতিশ্রুতিতে আগ্রহী হতে পারেন: github.com/couchdeveloper/RXPromise
e1985

0

এটি সম্পূর্ণ অনিচ্ছাকরণের মতো অনুভব করে তবে আমি মনে করি না এখানে সঠিক উত্তর আছে answer সাফল্য / ব্যর্থতা ব্লকগুলি ব্যবহার করার সময় ত্রুটি পরিচালনা করা এখনও সাফল্যের শর্তে করার প্রয়োজন হতে পারে বলে আমি সমাপ্তি ব্লকটি দিয়েছিলাম।

আমি মনে করি চূড়ান্ত কোডটি এমন কিছু দেখবে

[target taskWithCompletion:^(id object, NSError *error) {
    if (error) {
        // Oh noes! report the failure.
    } else if (![target validateObject:&object error:&error]) {
        // Oh noes! report the failure.
    } else {
        // W00t! I've got my object
    }
}];

বা সহজভাবে

[target taskWithCompletion:^(id object, NSError *error) {
    if (error || ![target validateObject:&object error:&error]) {
        // Oh noes! report the failure.
        return;
    }

    // W00t! I've got my object
}];

কোড এবং নেস্টিংয়ের সেরা অংশ নয় এটি আরও খারাপ হয়

[target taskWithCompletion:^(id object, NSError *error) {
    if (error || ![target validateObject:&object error:&error]) {
        // Oh noes! report the failure.
        return;
    }

    [object objectTaskWithCompletion:^(id object2, NSError *error) {
        if (error || ![object validateObject2:&object2 error:&error]) {
            // Oh noes! report the failure.
            return;
        }

        // W00t! I've got object and object 2
    }];
}];

আমি মনে করি আমি কিছুক্ষণের জন্য মপকে যাব।

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