প্রতিশ্রুতি। সমস্ত: সমাধান হওয়া মানগুলির ক্রম


188

এ খুঁজছি MDN এটা দেখে মনে হচ্ছে valuesপ্রেরণ then()Promise.all এর কলব্যাক প্রতিশ্রুতি অনুক্রমে মান ধারণ করে। উদাহরণ স্বরূপ:

var somePromises = [1, 2, 3, 4, 5].map(Promise.resolve);
return Promise.all(somePromises).then(function(results) {
  console.log(results) //  is [1, 2, 3, 4, 5] the guaranteed result?
});

যে আদেশটি valuesহওয়া উচিত তা কি কেউ একটি বিশ্লেষণের উদ্ধৃতি দিতে পারেন?

পিএস: এর মতো চলমান কোডটি দেখিয়েছিল যে এটি সত্য বলে মনে হচ্ছে যদিও এটি অবশ্যই কোনও প্রমাণ নয় - এটি কাকতালীয় হতে পারে।

উত্তর:


271

শীঘ্রই, আদেশ সংরক্ষণ করা হয়

বৈশিষ্ট আপনি লিঙ্ক অনুসরণ করে Promise.all(iterable)একটি সময় লাগে iterable(যে, একটি বস্তুর যে সমর্থন Iteratorইন্টারফেস) একটি প্যারামিটার হিসাবে এবং পরে কল PerformPromiseAll( iterator, constructor, resultCapability)এটা দিয়ে, ওভার যেখানে আধুনিক লুপ iterableব্যবহার IteratorStep(iterator)
এর অর্থ এই যে আপনি যদি পুনরাবৃত্তি করতে পারেন তবে যদি Promise.all()কঠোরভাবে আদেশ করা হয় তবে তাদের একবার প্রবেশ করার পরেও আদেশ দেওয়া হবে।

সমাধানের বাস্তবায়ন হয় Promise.all() Resolveযেখানে প্রতিটি সমাধান প্রতিশ্রুতিতে একটি অভ্যন্তরীণ [[Index]]স্লট থাকে যা মূল ইনপুটটিতে প্রতিশ্রুতির সূচক চিহ্নিত করে।


এর সমস্ত অর্থ হ'ল আউটপুট কঠোরভাবে ইনপুট হিসাবে অর্ডার করা হয় যতক্ষণ ইনপুট কঠোরভাবে অর্ডার করা হয় (উদাহরণস্বরূপ, একটি অ্যারে)।

আপনি এটি নীচের ফিডল (ES6) এ ক্রিয়াতে দেখতে পারেন:

// Used to display results
const write = msg => {
  document.body.appendChild(document.createElement('div')).innerHTML = msg;
};

// Different speed async operations
const slow = new Promise(resolve => {
  setTimeout(resolve, 200, 'slow');
});
const instant = 'instant';
const quick = new Promise(resolve => {
  setTimeout(resolve, 50, 'quick');
});

// The order is preserved regardless of what resolved first
Promise.all([slow, instant, quick]).then(responses => {
  responses.map(response => write(response));
});


1
কীভাবে পুনরাবৃত্তিযোগ্যকে কঠোরভাবে আদেশ করা হবে না? যে কোনও পুনরাবৃত্তযোগ্য তার মানটি তৈরি করে সেই আদেশের দ্বারা "কঠোরভাবে আদেশ করা" হয়
বেনজামিন গ্রুইনবাউম

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

3
@ বেনজামিন গ্রুয়েনবাউম কি পুনরাবৃত্তি হওয়ার পরে পৃথক দুটি অর্ডার তৈরি করার মতো পুনরাবৃত্ত হওয়া সম্ভব নয়? উদাহরণস্বরূপ, কার্ডগুলির একটি ডেক যা পুনরাবৃত্তি হয় যখন এলোমেলো ক্রমে কার্ড উত্পাদন করে? আমি জানি না "কঠোরভাবে আদেশ করা" এখানে সঠিক পরিভাষা কিনা তবে সমস্ত পুনরাবৃত্ত লোকের একটি নির্দিষ্ট অর্ডার থাকে না। তাই আমি মনে করি এটা বলতে চাই যে যুক্তিসঙ্গত এর iterators "কঠোরভাবে আদেশ" হয় (বলা যাচ্ছে যে অধিকার শব্দটি এর), কিন্তু iterables নয়।
জেএলআরিশ

3
@ জেএলআরহী আমি অনুমান করি আপনি ঠিক বলেছেন, এটি অবশ্যই পুনরাবৃত্তকারীকে আদেশ করা হয় - পুনরাবৃত্ত হয় না।
বেনজামিন গ্রুয়েনবাউম

8
প্রতিশ্রুতিগুলি শৃঙ্খলিত হয় না তা লক্ষণীয়। আপনি একই ক্রমে রেজোলিউশনটি পেয়ে যাবেন, প্রতিশ্রুতিগুলি কখন কার্যকর হয় সে সম্পর্কে কোনও গ্যারান্টি নেই। অন্য কথায়, Promise.allএকের পর এক প্রতিশ্রুতিগুলির বিন্যাস চালাতে ব্যবহার করা যাবে না। পূর্বাভাসের সাথে কাজ করার জন্য পুনরাবৃত্তিতে লোড হওয়া প্রতিশ্রুতিগুলির একে অপরের থেকে স্বতন্ত্র হওয়া দরকার।
অ্যান্ড্রু এডি

48

পূর্ববর্তী উত্তরগুলি ইতিমধ্যে বলেছে, Promise.allমূল প্রতিশ্রুতিগুলির ইনপুট ক্রমের সাথে সম্পর্কিত একটি অ্যারের সাথে সমস্ত সমাধান করা মানকে একত্রিত করে ( একত্রিত প্রতিশ্রুতি দেখুন )।

তবে, আমি উল্লেখ করতে চাই, ক্রমটি কেবল ক্লায়েন্টের পক্ষেই সংরক্ষিত!

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

এখানে একটি উদাহরণ যা টাইমআউটগুলি ব্যবহার করে সমস্যাটি দেখায়:

Promise.all

const myPromises = [
  new Promise((resolve) => setTimeout(() => {resolve('A (slow)'); console.log('A (slow)')}, 1000)),
  new Promise((resolve) => setTimeout(() => {resolve('B (slower)'); console.log('B (slower)')}, 2000)),
  new Promise((resolve) => setTimeout(() => {resolve('C (fast)'); console.log('C (fast)')}, 10))
];

Promise.all(myPromises).then(console.log)

উপরে প্রদর্শিত কোডটিতে তিনটি প্রতিশ্রুতি (এ, বি, সি) দেওয়া হয়েছে Promise.all। তিনটি প্রতিশ্রুতি বিভিন্ন গতিতে কার্যকর করা হয় (সি সবচেয়ে দ্রুত এবং বি সবচেয়ে ধীর হচ্ছে)। এই কারণেই console.logপ্রতিশ্রুতিগুলির বিবৃতি এই ক্রমে প্রদর্শিত হয়:

C (fast) 
A (slow)
B (slower)

প্রতিশ্রুতিগুলি যদি এজেএক্স কল হয়, তবে একটি দূরবর্তী ব্যাকএন্ড এই ক্রমে এই মানগুলি গ্রহণ করবে। তবে ক্লায়েন্টের পক্ষ থেকে Promise.allনিশ্চিত হয় যে ফলাফলগুলি myPromisesঅ্যারের মূল অবস্থান অনুসারে অর্ডার করা হয়েছে । সে কারণেই চূড়ান্ত ফলাফল:

['A (slow)', 'B (slower)', 'C (fast)']

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

সিকোয়েন্সিয়াল প্রতিশ্রুতি সারি

const PQueue = require('p-queue');
const queue = new PQueue({concurrency: 1});

// Thunked Promises:
const myPromises = [
  () => new Promise((resolve) => setTimeout(() => {
    resolve('A (slow)');
    console.log('A (slow)');
  }, 1000)),
  () => new Promise((resolve) => setTimeout(() => {
    resolve('B (slower)');
    console.log('B (slower)');
  }, 2000)),
  () => new Promise((resolve) => setTimeout(() => {
    resolve('C (fast)');
    console.log('C (fast)');
  }, 10))
];

queue.addAll(myPromises).then(console.log);

ফলাফল

A (slow)
B (slower)
C (fast)

['A (slow)', 'B (slower)', 'C (fast)']

2
দুর্দান্ত উত্তর, স্পষ্টভাবে PQueue ব্যবহার করে
আইরনস্টাইন

আমার একটি সিক্যুয়াল প্রতিশ্রুতি সারি দরকার, তবে ফলাফল স্কেল রেকর্ড থেকে এটি করতে হলে আমাকে কীভাবে তা করা যায়? একটি জন্য? যখন?, ES2017 আমাদের ES2018 এর কোনও বিকল্প নেই?
স্ট্যাকডেভ

PQueue আমাকে সাহায্য! ধন্যবাদ! :)
পোডেইগ

28

হ্যাঁ, মানগুলি resultsএকই ক্রমে হয় promises

কেউ ES6 টি নির্দিষ্ট করেPromise.all উল্লেখ করতে পারে যদিও ব্যবহৃত আয়রেটর এপিআই এবং জেনেরিক প্রতিশ্রুতিবদ্ধ নির্মাণকারীর কারণে এটি কিছুটা বিশৃঙ্খলাবদ্ধ। তবে, আপনি লক্ষ্য করবেন যে প্রতিটি রেজলভার কলব্যাকের একটি [[index]]বৈশিষ্ট্য রয়েছে যা প্রতিশ্রুতি-অ্যারে পুনরাবৃত্তিতে তৈরি হয়েছিল এবং ফলাফল অ্যারেতে মান নির্ধারণের জন্য ব্যবহৃত হয়।


আজব, আজ আমি একটি ইউটিউব ভিডিও দেখেছি যে বলেছে যে আউটপুট ক্রমটি প্রথমে নির্ধারিত হয় কে সমাধান করেছে, তারপরে দ্বিতীয়, তারপরে ..... আমার ধারণা ভিডিও ওপি কি ভুল ছিল?
রই নমির

1
@ রায়নিমির: সম্ভবত তিনি ছিলেন।
বার্গি

@ ওজিল ওয়াট? সব কাল প্রতিশ্রুতি পূর্ণ হওয়ার পরে ক্রমানুক্রমিক ক্রম সংক্রান্ত ক্রমটি বিবেচনা করে না। ফলাফল অ্যারেতে মানগুলির ক্রম প্রতিশ্রুতির ইনপুট অ্যারের মতোই। যদি তা না হয় তবে আপনার যথাযথ প্রতিশ্রুতি বাস্তবায়নে স্যুইচ করা উচিত।
বার্গি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.