অ্যারে.ম্যাপের সাথে অ্যাসিঙ্ক অপেক্ষা করুন ব্যবহার করুন


170

নিম্নলিখিত কোড দেওয়া:

var arr = [1,2,3,4,5];

var results: number[] = await arr.map(async (item): Promise<number> => {
        await callAsynchronousOperation(item);
        return item + 1;
    });

যা নিম্নলিখিত ত্রুটি উত্পন্ন করে:

TS2322: টাইপ করুন 'প্রতিশ্রুতি <নাম্বার> []' টাইপ 'নম্বর []' টাইপ করার যোগ্য নয়। টাইপ 'প্রতিশ্রুতি <সংখ্যা> টাইপ' নম্বর 'টাইপ করার যোগ্য নয়।

আমি কীভাবে এটি ঠিক করতে পারি? আমি কীভাবে তৈরি async awaitএবং Array.mapএকসাথে কাজ করতে পারি ?


6
কেন আপনি অ্যাসিঙ্ক অপারেশনটিতে একটি সিঙ্ক্রোনাস অপারেশন করার চেষ্টা করছেন? arr.map()সিঙ্ক্রোনাস এবং কোনও প্রতিশ্রুতি দেয় না।
jਫਰ00

2
আপনি কোনও ফাংশনে অ্যাসিক্রোনাস অপারেশন প্রেরণ করতে পারবেন না, যেমন mapএকটি সিনক্রোনাসের প্রত্যাশা করে এবং এটি কাজ করবে বলে আশা করে।
হেরেটিক বানর

1
@ jfriend00 আমার অভ্যন্তরীণ ফাংশনে অনেক প্রতীক্ষিত বিবৃতি রয়েছে। এটি আসলে একটি দীর্ঘ ফাংশন এবং আমি এটিকে পাঠযোগ্যযোগ্য করে তুলতে কেবল এটি সরলীকরণ করেছি। কেন এটি অ্যাসিঙ্ক হওয়া উচিত তা পরিষ্কার করার জন্য আমি এখন একটি প্রতীক্ষিত কল যুক্ত করেছি।
Alon

আপনাকে এমন কিছু অপেক্ষা করতে হবে যা প্রতিশ্রুতি দেয়, এমন কিছু নয় যা অ্যারে ফেরত দেয়।
jender00

2
একটি দরকারী জিনিস অনুধাবন করা হয় যে যতবার আপনি কোনও ফাংশন হিসাবে চিহ্নিত করেন async, আপনি সেই ফাংশনটিকে কোনও প্রতিশ্রুতি ফিরিয়ে দিচ্ছেন। অবশ্যই, অ্যাসিঙ্কের একটি মানচিত্র প্রতিশ্রুতির একটি বিন্যাস ফেরত দিয়েছে :)
অ্যান্টনি ম্যানিং-ফ্র্যাঙ্কলিন

উত্তর:


380

এখানে সমস্যাটি হ'ল আপনি awaitপ্রতিশ্রুতি না দিয়ে প্রতিশ্রুতিগুলির বিন্যাসে চেষ্টা করছেন । এটি আপনার প্রত্যাশা মতো করে না।

যখন অবজেক্টটি awaitকোনও প্রতিশ্রুতি awaitহিসাবে প্রেরণ করা হয় না, কেবল সমাধান করার চেষ্টা করার পরিবর্তে অবিলম্বে মানটি প্রদান করে। সুতরাং যেহেতু আপনি awaitএখানে প্রতিশ্রুতির পরিবর্তে একটি অ্যারের (প্রতিশ্রুতি অবজেক্টগুলির) পাশ করেছেন, প্রতীক্ষিত দ্বারা প্রত্যাবর্তিত মানটি কেবল সেই অ্যারে হয়, যা টাইপ Promise<number>[]

আপনাকে এখানে যা করতে হবে তা হ'ল Promise.allঅ্যারে দিয়ে কল mapকরার জন্য এটি এং করার আগে awaitএটি একটি প্রতিশ্রুতিতে রূপান্তর করতে।

এমডিএন ডক্সPromise.all অনুসারে :

Promise.all(iterable)পদ্ধতি একটি প্রতিশ্রুতি ফেরৎ যে সমাধান করা যখন iterable যুক্তি সমস্ত প্রতিজ্ঞা সমাধান করেছি, বা প্রথম গৃহীত অঙ্গীকার করা হয়েছে যে প্রত্যাখ্যান ঘষার কারন দিয়া প্রত্যাখ্যান করে।

সুতরাং আপনার ক্ষেত্রে:

var arr = [1, 2, 3, 4, 5];

var results: number[] = await Promise.all(arr.map(async (item): Promise<number> => {
    await callAsynchronousOperation(item);
    return item + 1;
}));

আপনি এখানে যে নির্দিষ্ট ত্রুটির মুখোমুখি হচ্ছেন এটি এটি সমাধান করবে।


1
কী করতে :কোলন মানে?
ড্যানিয়েল মনিকাকে

11
@ ড্যানিয়েলপেন্ডারগাস্ট এটি টাইপস্ক্রিপ্টে টাইপ টীকাগুলির জন্য।
Ajedi32

অ্যাসিঙ্ক ম্যাপ ফাংশনটির callAsynchronousOperation(item);সাথে এবং তার বাইরে কল করার মধ্যে পার্থক্য কী await?
নারডিজল

@nerdizzle এটি অন্য প্রশ্নের জন্য ভাল প্রার্থী বলে মনে হচ্ছে। মূলত যদিও, awaitক্রিয়াকলাপটি চালিয়ে যাওয়ার আগে অ্যাসিনক্রোনাস অপারেশনটি সম্পূর্ণ হওয়ার (বা ব্যর্থ) অপেক্ষা করবে, অন্যথায় এটি অপেক্ষা না করে কেবল অবিলম্বে চালিয়ে যাবে।
আজেদি 32

প্রতিক্রিয়া জন্য @ Ajedi32 thx। তবে অ্যাসিঙ্ক মানচিত্রে অপেক্ষা না করে ফাংশনটির পুনরায় ফলাফলের জন্য অপেক্ষা করা আর কি সম্ভব নয়?
নারডিজল

15

যদি আপনি দেশীয় প্রতিশ্রুতিগুলি না ব্যবহার করেন তবে ব্লুবার্ড ব্যবহার করছেন তবে এর জন্য আরও একটি সমাধান রয়েছে।

আপনি অ্যারে.ম্যাপ এবং প্রতিশ্রুতি.সকল মিশ্রন করে, প্রতিশ্রুতি.ম্যাপ () ব্যবহার করার চেষ্টা করতে পারেন

আপনার ক্ষেত্রে:

  var arr = [1,2,3,4,5];

  var results: number[] = await Promise.map(arr, async (item): Promise<number> => {
    await callAsynchronousOperation(item);
    return item + 1;
  });

2
এটি ভিন্ন - এটি সমান্তরালভাবে সমস্ত ক্রিয়াকলাপ চালায় না, বরং ক্রমানুসারে তাদের চালায়।
Andrey Tserkus

5
@ অ্যান্ড্রেটসারকাস Promise.mapSeriesবা ক্রমযুক্ত Promise.each, Promise.mapএগুলি একবারে শুরু করে।
কিচলস

1
অ্যান্ড্রেটসারকাস আপনি concurrencyবিকল্প সরবরাহ করে সমান্তরালভাবে সমস্ত বা কিছু ক্রিয়াকলাপ চালাতে পারেন ।

11
এটি উল্লেখযোগ্য যে এটি কোনও ভ্যানিলা জেএস নয়।
মিশাল

@ মিশল হ্যাঁ, এটি
সিনট্যাক্স এরর

6

আপনি যদি প্রতিশ্রুতিগুলির একটি অ্যারে মানচিত্র করেন তবে আপনি সেগুলি সংখ্যার অ্যারেতে সমাধান করতে পারেন। দেখুন Promise.all


2

আমি উপরোক্ত হিসাবে প্রতিশ্রুতি.এলটি ব্যবহার করার পরামর্শ দিচ্ছি, তবে যদি আপনি সত্যিই এই পদ্ধতির এড়ানো পছন্দ করেন তবে আপনি বা অন্য কোনও লুপের জন্য এটি করতে পারেন:

const arr = [1,2,3,4,5];
let resultingArr = [];
for (let i in arr){
  await callAsynchronousOperation(i);
  resultingArr.push(i + 1)
}

6
প্রতিশ্রুতি। সমস্ত অ্যারের প্রতিটি উপাদানগুলির জন্য অ্যাসিঙ্ক হবে। এটি একটি সিঙ্ক হবে, পরেরটি শুরু করতে এটির একটি উপাদান শেষ করতে অপেক্ষা করতে হবে।
সান্টিয়াগো মেন্দোজা রামিরেজ

যারা এই পদ্ধতির চেষ্টা করছেন তাদের জন্য, মনে রাখবেন যে বিন্যাসে অ্যারে সামগ্রীর পুনরাবৃত্তি করার সঠিক উপায় হ'ল, যখন সূচকগুলি থেকে পুনরাবৃত্তি হয়।
ralfoide

2

একটি অ্যারের সমস্ত উপাদানকে অবিচ্ছিন্নভাবে প্রক্রিয়াজাত করতে এবং আদেশ সংরক্ষণ করার জন্য নীচের সমাধান:

const arr = [1, 2, 3, 4, 5, 6, 7, 8];
const randomDelay = () => new Promise(resolve => setTimeout(resolve, Math.random() * 1000));

const calc = async n => {
  await randomDelay();
  return n * 2;
};

const asyncFunc = async () => {
  const unresolvedPromises = arr.map(n => calc(n));
  const results = await Promise.all(unresolvedPromises);
};

asyncFunc();

এছাড়াও codepen

লক্ষ্য করুন আমরা কেবলমাত্র প্রতিশ্রুতির জন্য "অপেক্ষা" করছি। আমরা একাধিকবার "অপেক্ষা" না করে কলকে কল করি এবং আমরা এখনই অমীমাংসিত প্রতিশ্রুতির একটি অ্যারে সংগ্রহ করি। তারপরে প্রতিশ্রুতি.আলগুলি তাদের সকলের সমাধানের জন্য অপেক্ষা করে এবং সমাধান হওয়া মানগুলির সাথে ক্রম অনুযায়ী একটি অ্যারে প্রদান করে।

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