#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 ---'); } });