অসম্পূর্ণ / প্রতীক্ষিত অন্তর্নিহিত প্রতিশ্রুতি ফেরত?


111

আমি পড়েছি যে asyncকীওয়ার্ড দ্বারা চিহ্নিত অ্যাসিঙ্ক ফাংশনগুলি স্পষ্টভাবে একটি প্রতিশ্রুতি ফিরিয়ে দেয়:

async function getVal(){
 return await doSomethingAync();
}

var ret = getVal();
console.log(ret);

কিন্তু যে সুসঙ্গত ... অভিমানী নয় doSomethingAsync()আয় একটি প্রতিশ্রুতি, এবং অপেক্ষা শব্দ প্রতিশ্রুতি থেকে মান ফিরে আসবো, না প্রতিজ্ঞা itsef, তারপর আমার getVal ফাংশন উচিত যে মান, কোনো অন্তর্নিহিত প্রতিশ্রুতি ফিরে যান।

তাহলে কেস ঠিক কী? অ্যাসিঙ্ক কীওয়ার্ড দ্বারা চিহ্নিত ফাংশনগুলি কি স্পষ্টভাবে প্রতিশ্রুতি দেয় বা আমরা কী ফিরে আসে তা নিয়ন্ত্রণ করি?

সম্ভবত আমরা যদি স্পষ্টভাবে কিছু ফেরত না পাই, তবে তারা স্পষ্টতই একটি প্রতিশ্রুতি ফিরিয়ে দেয় ...?

আরও স্পষ্ট করে বলতে গেলে, উপরোক্ত এবং এর মধ্যে পার্থক্য রয়েছে

function doSomethingAync(charlie) {
    return new Promise(function (resolve) {
        setTimeout(function () {
            resolve(charlie || 'yikes');
        }, 100);
    })
}

async function getVal(){
   var val = await doSomethingAync();  // val is not a promise
   console.log(val); // logs 'yikes' or whatever
   return val;  // but this returns a promise
}

var ret = getVal();
console.log(ret);  //logs a promise

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


1
কি console.logদেখায়?
বার্মার

এটি প্রতিশ্রুতি সমাধানের ক্রিয়াকলাপের মাধ্যমে পাস হওয়া মান, প্রতিশ্রুতি নিজেই নয়
আলেকজান্ডার মিলস

প্রতিশ্রুতি থেকে ফলাফল খোলার জন্য সম্ভবত অপেক্ষা করুন।
হ্যামলেট হাকোবায়ান

আসলে, আমি ভুল ছিলাম, এটি একটি প্রতিশ্রুতি লগ করেছে
আলেকজান্ডার মিলস

2
জাভাস্ক্রিপ্ট এর প্রতিশ্রুতি c # এর async আচরণের জন্য অপেক্ষা করছে। যাইহোক, সি # এর সাথে এটি সমর্থন করার জন্য historতিহাসিকভাবে অনেকগুলি কাঠামো ছিল এবং জাভাস্ক্রিপ্টে কোনওটিই ছিল না। সুতরাং অনেকগুলি ব্যবহারের ক্ষেত্রে এটি খুব একই রকমের বলে মনে হতে পারে, এটি কিছুটা মিসনোমার।
ট্র্যাভিস জে

উত্তর:


136

রিটার্ন মান সর্বদা একটি প্রতিশ্রুতি হবে। আপনি যদি স্পষ্টভাবে কোনও প্রতিশ্রুতি না ফিরিয়ে দেন তবে আপনি যে মানটি ফিরিয়ে দেন তা স্বয়ংক্রিয়ভাবে কোনও প্রতিশ্রুতিতে আবৃত হবে।

async function increment(num) {
  return num + 1;
}

// Even though you returned a number, the value is
// automatically wrapped in a promise, so we call
// `then` on it to access the returned value.
//
// Logs: 4
increment(3).then(num => console.log(num));

একই জিনিস এমনকি যদি একটি আছে await

function defer(callback) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve(callback());
    }, 1000);
  });
}

async function incrementTwice(num) {
  const numPlus1 = await defer(() => num + 1);
  return numPlus1 + 1;
}

// Logs: 5
incrementTwice(3).then(num => console.log(num));

স্বতঃ-মোড়ক দেওয়ার প্রতিশ্রুতি দেয়, সুতরাং যদি আপনি কোনও asyncফাংশন থেকে কোনও মানের জন্য প্রতিশ্রুতি ফিরিয়ে দেন তবে আপনি মানটির জন্য একটি প্রতিশ্রুতি পাবেন (মানটির জন্য কোনও প্রতিশ্রুতির জন্য প্রতিশ্রুতি নয়)।

function defer(callback) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve(callback());
    }, 1000);
  });
}

async function increment(num) {
  // It doesn't matter whether you put an `await` here.
  return defer(() => num + 1);
}

// Logs: 4
increment(3).then(num => console.log(num));

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

ES6 এর ফাংশন রয়েছে যা ঠিক একই মানটি দেয় না return। এই ফাংশনগুলিকে জেনারেটর বলা হয়।

function* foo() {
  return 'test';
}

// Logs an object.
console.log(foo());

// Logs 'test'.
console.log(foo().next().value);

3
"আপনার প্রত্যাবর্তিত মানটি স্বয়ংক্রিয়ভাবে একটি প্রতিশ্রুতিতে আবৃত হয়ে যাবে" স্থির পদ্ধতি দ্বারা প্রতিশ্রুতি। এটি স্পষ্টভাবে হয়ে যায় - রিটার্ন প্রতিশ্রুতি। রিলিজ (এক্স);
আদনান

সুস্পষ্টভাবে নিজেকে তৈরি করার পরিবর্তে স্বয়ংক্রিয়ভাবে তৈরি প্রতিশ্রুতি ফিরিয়ে দেওয়া কি খারাপ অভ্যাস হিসাবে বিবেচিত হবে? একরকম আমি অনেক ক্ষেত্রে পরিষ্কার পদ্ধতি পছন্দ করি।
মার্লার

24

আমি অনুমানটি একবার দেখে নিচের তথ্যগুলি পেয়েছি। সংক্ষিপ্ত সংস্করণটি হ'ল async functionজেনারেটরের কাছে একটি ডিজুগার যা ফল দেয় Promise। সুতরাং, হ্যাঁ, অ্যাসিঙ্ক ফাংশনগুলি প্রতিশ্রুতি ফেরায়

টিসি 39 অনুমান অনুসারে নিম্নলিখিতটি সত্য:

async function <name>?<argumentlist><body>

ডিজুগারগুলি:

function <name>?<argumentlist>{ return spawn(function*() <body>, this); }

যেখানে spawn"নিম্নলিখিত অ্যালগরিদমে কল আছে":

function spawn(genF, self) {
    return new Promise(function(resolve, reject) {
        var gen = genF.call(self);
        function step(nextF) {
            var next;
            try {
                next = nextF();
            } catch(e) {
                // finished with failure, reject the promise
                reject(e);
                return;
            }
            if(next.done) {
                // finished with success, resolve the promise
                resolve(next.value);
                return;
            }
            // not finished, chain off the yielded promise and `step` again
            Promise.resolve(next.value).then(function(v) {
                step(function() { return gen.next(v); });
            }, function(e) {
                step(function() { return gen.throw(e); });
            });
        }
        step(function() { return gen.next(undefined); });
    });
}

"সংক্ষিপ্ত সংস্করণটি হ'ল একটি অ্যাসিঙ্ক ফাংশন এমন একটি জেনারেটরের নিকটে ইচ্ছে করে যা প্রতিশ্রুতি দেয়" " আমি তোমাদের বিভ্রান্তিকর করা হতে পারে মনে async functionসঙ্গে async function*। প্রাক্তন কেবল একটি প্রতিশ্রুতি ফিরে। পরেরটি একটি জেনারেটর দেয় যা প্রতিশ্রুতি দেয়।
cdowie

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


-3

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

আমার মনে হয় সিনট্যাক্সটি (আমি 100% নিশ্চিত নই)

async function* getVal() {...}

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

db.exec(function*(connection) {
  if (params.passwd1 === '') {
    let sql = 'UPDATE People SET UserName = @username WHERE ClinicianID = @clinicianid';
    let request = connection.request(sql);
    request.addParameter('username',db.TYPES.VarChar,params.username);
    request.addParameter('clinicianid',db.TYPES.Int,uid);
    yield connection.execSql();
  } else {
    if (!/^\S{4,}$/.test(params.passwd1)) {
      response.end(JSON.stringify(
        {status: false, passwd1: false,passwd2: true}
      ));
      return;
    }
    let request = connection.request('SetPassword');
    request.addParameter('userID',db.TYPES.Int,uid);
    request.addParameter('username',db.TYPES.NVarChar,params.username);
    request.addParameter('password',db.TYPES.VarChar,params.passwd1);
    yield connection.callProcedure();
  }
  response.end(JSON.stringify({status: true}));

}).catch(err => {
  logger('database',err.message);
  response.end(JSON.stringify({status: false,passwd1: false,passwd2: false}));
});

লক্ষ্য করুন আমি কীভাবে এটি বিশেষভাবে সাধারণ সিঙ্ক্রোনাসের মতো প্রোগ্রাম করি

yield connection.execSql এবং এ yield connection.callProcedure

Db.exec ফাংশনটি মোটামুটি সাধারণ প্রতিশ্রুতি ভিত্তিক জেনারেটর

exec(generator) {
  var self = this;
  var it;
  return new Promise((accept,reject) => {
    var myConnection;
    var onResult = lastPromiseResult => {
      var obj = it.next(lastPromiseResult);
      if (!obj.done) {
        obj.value.then(onResult,reject);
      } else {
       if (myConnection) {
          myConnection.release();
        }
        accept(obj.value);
      }
    };
    self._connection().then(connection => {
      myConnection = connection;
      it = generator(connection); //This passes it into the generator
      onResult();  //starts the generator
    }).catch(error => {
      reject(error);
    });
  });
}

4
" অ্যাসিঙ্ক একটি বর্ধিত জেনারেটর ফাংশন " - না, এটি আসলে তা নয়।
বার্গি

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

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