Обещание не работает в Cron Работа в NodeJS

#javascript #node.js #async-await #promise #es6-promise

Вопрос:

Обещание не работает внутри cronjob в nodejs.

позвольте мне объяснить свой вопрос с помощью этого кода.

У меня есть один крон, который запускается каждые пять секунд.

Теперь внутри cron у меня есть одна функция client.statistics, и я думаю, что это займет некоторое время. поэтому мне нужно дождаться этого, а затем выполнить приведенный ниже код.

Проблема: Проблема в том, что я использую этот код без обещания, поэтому я знаю, что без обещания это не сработало. теперь я использую обещание для ожидания этого времени функции, но в настоящее время оно не работает.

Я использую обещание, и теперь мой выход вот так.

вывод: — НАЧАЛО CRON — ДАТА И ВРЕМЯ 2021-10-22 11:41:10

это не выполняется ниже кода, не знаю, что здесь происходит

Что мне нужно: Мне нужно сначала выполнить верхний код, затем обещать код, а затем последний код, такой как консоль, например, end cron.

Спасибо заранее. 🙂

 const twelvedata = require("twelvedata");  cron.schedule('*/5 * * * * *', () =gt; {  var today = new Date();  var datetime = today.getFullYear()   '-'   (today.getMonth()   1)   '-'   today.getDate()   ' '   today.getHours()   ":"   today.getMinutes()   ":"   today.getSeconds();  console.log('--- CRON START ---');  console.log('DATE-TIME', datetime);  let symbol = "5PAISA";  let params = {  symbol:symbol,  exchange: "NSE",  country: "India",  };   let mypromise = function functionOne(){  const client = twelvedata(config);  return new Promise((resolve ,reject)=gt;{  client.statistics(params).then((data) =gt; {  console.log("All Worked",data);  resolve("Resolved");  }).catch((error) =gt; {  console.log('Error', error);  reject("Rejected")  });  });  };   mypromise().then((res)=gt;{  console.log(`The function recieved with value ${res}`)  console.log('--- CRON END ---');  return datetime;  }).catch((error)=gt;{  console.log(`Handling error as we received ${error}`);  console.log('ERROR');  return false;  });   console.log('--- CRON FINISHED ---');  });  

Комментарии:

1. Вы не можете изменить это, чтобы использовать async / await? Несколько уровней вложенных вызовов функций, которые вы используете здесь, значительно увеличили когнитивные издержки вашего кода.

Ответ №1:

Во-первых new Promise((resolve ,reject)=gt;{ … }) , это анти-шаблон, потому что внутри него вы создаете цепочку обещаний.

Также reject("Rejected") часто рассматривается как анти-шаблон, потому reject("Rejected") что считается, что он эквивалентен значению throw "Rejected" , и вы должны выдавать только фактические ошибки.

console.log('--- CRON FINISHED ---'); не ждет завершения цепочки обещаний, а вызывается немедленно.

Вот очищенная версия вашего кода.

 const twelvedata = require("twelvedata");  cron.schedule('*/5 * * * * *', () =gt; {  var today = new Date();  var datetime = today.getFullYear()   '-'   (today.getMonth()   1)   '-'   today.getDate()   ' '   today.getHours()   ":"   today.getMinutes()   ":"   today.getSeconds();  console.log('--- CRON START ---');  console.log('DATE-TIME', datetime);   let symbol = "5PAISA";  let params = {  symbol: symbol,  exchange: "NSE",  country: "India",  };    twelvedata(config)  .statistics(params)  .then((data) =gt; {  console.log("All Worked", data);  return "Resolved"  }).catch((error) =gt; {  console.log('Error', error);  return "Rejected"  }).then((res) =gt; {  console.log(`The function recieved with value ${res}`)  console.log('--- CRON END ---');  // you don't make use of this returned value in your code ?  // return datetime;  }).catch((error) =gt; {  console.log(`Handling error as we received ${error}`);  console.log('ERROR');  // you don't make use of this returned value in your code ?  // return false;  })  .finally(() =gt; {  console.log('--- CRON FINISHED ---');  });   });  

Как я уже сказал reject("Rejected") , это антипаттерн, и в вашем случае непонятно, почему вы даже переводите фактическую ошибку, чтобы Rejected вы могли просто пропустить ошибку к себе console.log(`Handling error as we received ${error}`); .

 const twelvedata = require("twelvedata");  cron.schedule('*/5 * * * * *', () =gt; {  var today = new Date();  var datetime = today.getFullYear()   '-'   (today.getMonth()   1)   '-'   today.getDate()   ' '   today.getHours()   ":"   today.getMinutes()   ":"   today.getSeconds();  console.log('--- CRON START ---');  console.log('DATE-TIME', datetime);   let symbol = "5PAISA";  let params = {  symbol: symbol,  exchange: "NSE",  country: "India",  };    twelvedata(config)  .statistics(params)  .then((data) =gt; {  console.log("All Worked", data);  return "Resolved"  })  .then((res) =gt; {  console.log(`The function recieved with value ${res}`)  console.log('--- CRON END ---');  return datetime;  })  .catch((error) =gt; {  console.log(`Handling error as we received ${error}`);  console.log('ERROR');  return false;  })  .finally(() =gt; {  console.log('--- CRON FINISHED ---');  });   });  

Используя async и await может сделать все это еще более понятным.

 const twelvedata = require("twelvedata");  cron.schedule('*/5 * * * * *', async() =gt; {  var today = new Date();  var datetime = today.getFullYear()   '-'   (today.getMonth()   1)   '-'   today.getDate()   ' '   today.getHours()   ":"   today.getMinutes()   ":"   today.getSeconds();  console.log('--- CRON START ---');  console.log('DATE-TIME', datetime);   let symbol = "5PAISA";  let params = {  symbol: symbol,  exchange: "NSE",  country: "India",  };   // I commented that out because you acutall don't use that in your code, but is would it shows how to match your `return` statements in the promise chain.  // let result;   try {  const data = await twelvedata(config).statistics(params)  console.log("All Worked", data);  const res = "Resolved"   // result = datetime;  console.log(`The function recieved with value ${res}`);  console.log('--- CRON END ---');  } catch (error) {  // result = false;  console.log(`Handling error as we received ${error}`);  console.log('ERROR');  }   // console.log(result)   console.log('--- CRON FINISHED ---');  });  

И удаление всего, что, похоже, не используется:

 const twelvedata = require("twelvedata");  cron.schedule('*/5 * * * * *', async() =gt; {  var today = new Date();  var datetime = today.getFullYear()   '-'   (today.getMonth()   1)   '-'   today.getDate()   ' '   today.getHours()   ":"   today.getMinutes()   ":"   today.getSeconds();  console.log('--- CRON START ---');  console.log('DATE-TIME', datetime);   let symbol = "5PAISA";  let params = {  symbol: symbol,  exchange: "NSE",  country: "India",  };   try {  const data = await twelvedata(config).statistics(params)  console.log("All Worked", data);  console.log('--- CRON END ---');  } catch (error) {  console.log(`Handling error as we received ${error}`);  console.log('ERROR');  }    console.log('--- CRON FINISHED ---');  });  

Комментарии:

1. Да, это работает, спасибо 🙂

Ответ №2:

вместо того, чтобы возвращать новое обещание в functionOne попытке назначить обещание mypromise переменной.

 let mypromise = new Promise((resolve ,reject) =gt; {  const client = twelvedata(config);  client.statistics(params).then((data) =gt; {  console.log("All Worked",data);  resolve("Resolved");  }).catch((error) =gt; {  console.log('Error', error);  reject("Rejected")  });  });  

Теперь используйте его без вызова:

 mypromise.then((res)=gt;{  console.log(`The function recieved with value ${res}`)  console.log('--- CRON END ---');  return datetime;  }).catch((error)=gt;{  console.log(`Handling error as we received ${error}`);  console.log('ERROR');  return false;  }).finally(() =gt; {  console.log('--- CRON FINISHED ---')  })  

Комментарии:

1. Я попробовал ваш код, да, он работает нормально, но проблема в журнале, который я недавно добавил, пожалуйста, проверьте это. Таким образом, сначала вызывается журнал завершения работы консоли, а затем вызывается журнал ЗАВЕРШЕНИЯ работы. Почему это произошло? ваше решение почти в порядке, но этот последний поток, например, сначала завершает печать CRON, а затем ЗАВЕРШАЕТ CRON.

2. это правильное поведение, так как вы используете асинхронный метод. сначала '--- CRON FINISHED ---' регистрируется последнее, потому что это не асинхронное действие, затем выполняются асинхронные части. вы можете исправить это с finally помощью метода, я добавил это требование к ответу. @Даршанравал

3. Он также работает с вашим кодом. Спасибо 🙂

Ответ №3:

Вам не нужен собственный API-оболочка на основе обещаний, потому что api, который вы используете, уже возвращает обещания

Подумайте о том, чтобы переписать код, чтобы вы не использовали так много обещаний и вложенных обратных вызовов.

Эта (непроверенная) версия кода имеет только 2 уровня отступа , без обратных вызовов (игнорируя, что все это в вызове cron.расписание), и на 6 строк короче.

 const twelvedata = require("twelvedata");  cron.schedule('*/5 * * * * *', async () =gt; {  try  {  var today = new Date();  var datetime = today.getFullYear()   '-'   (today.getMonth()   1)   '-'   today.getDate()   ' '   today.getHours()   ":"   today.getMinutes()   ":"   today.getSeconds();  console.log('--- CRON START ---');  console.log('DATE-TIME', datetime);  let symbol = "5PAISA";  let params = {  symbol:symbol,  exchange: "NSE",  country: "India",  };    const client = twelvedata(config);  const data = await client.statistics(params);  console.log(`The function recieved with value ${data}`)  console.log('--- CRON END ---');  return datetime;  }  catch (error)  {  console.log(`Handling error as we received ${error}`);  console.log('ERROR');  return false;  }  finally  {  console.log('--- CRON FINISHED ---');  }  });