ובכלל איך רקורסיה עוזרת בפונקציה אי סינכרונית?
הלולאה יכולה להסתיים לפני תשובת הקול-בק הראשונה, ואז להתחיל לענות תשובות שלא לפי הסדר!
פורסם במקור בפורום CODE613 ב08/09/2015 15:23 (+03:00)
ובכלל איך רקורסיה עוזרת בפונקציה אי סינכרונית?
הלולאה יכולה להסתיים לפני תשובת הקול-בק הראשונה, ואז להתחיל לענות תשובות שלא לפי הסדר!
פורסם במקור בפורום CODE613 ב08/09/2015 15:23 (+03:00)
@דוד ל.ט.
אתה צריך לשנות את החשיבה. מה שאתה מעלה זה בכלל לא חסרונות של JS, בנו אותו דוקא לזה.
באמת נראה לי ששאילתות כמו שלך מDB לא כדאי לבצע אסינכרוני, כי אתה לא רוצה תוצאה של כל הקודם זוכה אלא לפי הסדר (המילה מקורית ורק אח"כ וריאציה א' ורק אח"כ וריאציה ב').
כשרוצים לעשות לפי סדר בJS הכי טוב זה להשתמש עם רשימה. משהו כזה:app.post("/", function (req, res) { searchFromDb('word', function(result) { if(!result) res.status(404).send('Not found'); else res.send(result); }); }); function searchFromDb(word, func) { var searchVariation = { word, word, word}; var getFromDb = function(index) { db.get(searchVariation[index], function (err, value) { if(err) { if(index < searchVariation.length) getFromDb(index++) else func(); } else { func(value) } } } getFromDb(0); }
באוסף searchVariation שמתי רשימה של אותה מילה אבל הכוונה לעשות וריאציות שונות. הבדיקה עליהם תופעל לפי סדר (רק במקרה כישלון של הראשון תתבצע בדיקה של השני).
אם עצם הכנת הוריאציות עולה ביצועים אתה יכול לוותר על רשימה אבל לעשות פונקציה שמקבלת את המקור ורשימה של מה שנוסה כבר ובודקת אם יש מה לנסות עוד.
במידה ויש לך וריאציות עם אותו עדיפות הכי טוב זה לשלוח אסינכרוני ו"כל הקודם זוכה" ככה אתה מרויח את מעלת הJS.
אוקי
אפשר למחוק פה עמוד שלם של שטויות שכתבתי
ברשותך, נחזור להתחלה
שאלות פשוטות של הבנה (שכמדומני שלאחריהם אחסוך ממכם הרבה שאלות נספות):
searchFromDb('word', function(result)
עד עכשיו חשבתי שפונקציות קול-בק זה קומבינה של פונקציות מסוימות, שמוגדר בהם לקרוא את הפונקציה השניה רק אחרי שמסיים
רק עכשיו (בזכות השורה הזו) אני קולט שזו השיטה הבסיסית לומר לJS לבצע פעולות בצורה סיכרונית.
לדוגמא אם אני רוצה להפעיל 3 פונקציות שכל אחת תופעל רק אחרי שהקודמת מסיימת, אני פותח פונקציה ומכניס כארגומנטים את שלושת הפונקציות.
הבנתי נכון?
עוד משהו שאני ממש משתומם
searchFromDb נמצא פעמיים ובכל פעם עם תוכן שונה בתוך ה-{ }.
אז בקריאה לפונקציה איזה מהם מתבצע??
אגב
mat ממשיך לטעון שמוכרחים להשתמש עם asinc.
פורסם במקור בפורום CODE613 ב08/09/2015 15:21 (+03:00)
באמת ההגיון אומר כך
אבל חיפשתי ולא מצאתי שם קבצי c.
פורסם במקור בפורום CODE613 ב08/09/2015 14:55 (+03:00)
@דוד ל.ט.
אבל מה זה קשור לנושא האשכול?
לא תירוץ מספיק טוב, ובכ"ז..
הגעתי לזה כי חשבתי על פונקציה שמקבלת בget מערך, ומחפש לפי סדר האיברים כל זמן שלא נמצא.
פורסם במקור בפורום CODE613 ב08/09/2015 13:53 (+03:00)
כאן יש הכנסה של הפונקציות לפרוטוטייפ
https://github.com/Level/levelup/blob/master/lib/levelup.js
כאן יש את העדכון
https://github.com/level/levelup/commit/187711c96c
בו החליפו את השימוש ב-codec.js למודול codec.
מאיפה המודול הזה נקרא? בנוד יש קבצים בינארים שמכילים הרבה, אבל פה לא רואה דבר כזה.
ואגב, אני כנראה לא בכיוון
חשבתי שאמצע שם את כל הניהול הבינארי, איך ש-level שומר את החומר
אבל הקובץ/מודול הנ"ל כנראה רק עוזר בניהול הקידודים.
בקיצור, יש עוד המון מה ללמוד..
פורסם במקור בפורום CODE613 ב07/09/2015 14:52 (+03:00)
אני מנסה טיפה להבין שם מה קורה
ורואה שההמרה לבינארי מגיע מכאן
Codec = require('level-codec')
אבל אין קובץ כזה
אז מאיפה זה נלקח?
פורסם במקור בפורום CODE613 ב07/09/2015 14:35 (+03:00)
רבי דוד
מה עושה
func(value)
מריץ את הפונקציה שעכשיו רצה (רקורסיה)?
שוב אלף תודות!!
כתיבה וחתימה טובה לכולם!
פורסם במקור בפורום CODE613 ב06/09/2015 22:41 (+03:00)
@דוד ל.ט.
במידה ויש לך וריאציות עם אותו עדיפות הכי טוב זה לשלוח אסינכרוני ו"כל הקודם זוכה" ככה אתה מרויח את מעלת הJS.
אין לי עדיפות באיזה מילה הוא מטפל קודם
אבל אני כן צריך שאת התוצאה הוא יכניס לאותו מיקום במערך, כמו של המילה שמחפשים.
בלולאה בסיסית הצלחתי
אבל כשנסיתי להוסיף נסיונות נוספים של חיפוש למקרה ולא מוצא
לא הצלחתי לשמר את מספר האינדקס.
פורסם במקור בפורום CODE613 ב06/09/2015 22:40 (+03:00)
@דוד ל.ט.
אתה צריך לשנות את החשיבה. מה שאתה מעלה זה בכלל לא חסרונות של JS, בנו אותו דוקא לזה.
באמת נראה לי ששאילתות כמו שלך מDB לא כדאי לבצע אסינכרוני, כי אתה לא רוצה תוצאה של כל הקודם זוכה אלא לפי הסדר (המילה מקורית ורק אח"כ וריאציה א' ורק אח"כ וריאציה ב').
כשרוצים לעשות לפי סדר בJS הכי טוב זה להשתמש עם רשימה. משהו כזה:
אני לא באמת חושב שזה חסרון....
רוצה ללמוד איך כן מתנהגים עם זה.
פורסם במקור בפורום CODE613 ב06/09/2015 22:13 (+03:00)
@אהרן
@softs
אכן js היא שפה מאוד שונה משפות אחרות והמבנה שלה נוח מאוד לעבודה אסינכרונית, צריך ללמוד לחיות עם זה ולא להילחם בזה.אני ממתין לך בסבלנות
ואתה בורח אחרי שורה אחת?
אז עכשיו אנשים "בונים" עלי שאני יענה? מלחיץ קצת כי אני די מרגיש בור בהרבה דברים...
אני פשוט זוכר את עצמי מנסה להילחם באסינכרוניות ומכלה את כוחותי לריק אז נתתי עצה טובה.
לגבי השאלה הספציפית לא העמקתי בענין, ומי לנו גדול מדוד ל.ט. שכבר נראה שלן בעומקה של שאלתך והשקיע מזמנו ללמוד את הנושא במיוחד!
הלוואי על כולנו...
אגב ל jquery יש אופציה ל AJAX סינכרוני שמשתמש באובייקט הגנרי של JS (http://stackoverflow.com/questions/3481970/how-does-jquerys-synchronous-ajax-request-work)
אם הבנתי נכון מדובר רק על האם להמתין לתשובה מבלי להמשיך בקוד
ולכן זה עלול להקפיא את הדפדפן לדקות ארוכות (עד שמגיעה תשובה),
ואם אני מבין נכון, זה בכל מקרה לא ישפיע על פונקציות אי סינכרוניות שהשרת קורא להם ואין לajax שום שליטה עליהם.
פורסם במקור בפורום CODE613 ב06/09/2015 21:43 (+03:00)
@דוד ל.ט.
אתה צריך לשנות את החשיבה. מה שאתה מעלה זה בכלל לא חסרונות של JS, בנו אותו דוקא לזה.
באמת נראה לי ששאילתות כמו שלך מDB לא כדאי לבצע אסינכרוני, כי אתה לא רוצה תוצאה של כל הקודם זוכה אלא לפי הסדר (המילה מקורית ורק אח"כ וריאציה א' ורק אח"כ וריאציה ב').
כשרוצים לעשות לפי סדר בJS הכי טוב זה להשתמש עם רשימה. משהו כזה:app.post("/", function (req, res) { searchFromDb('word', function(result) { if(!result) res.status(404).send('Not found'); else res.send(result); }); }); function searchFromDb(word, func) { var searchVariation = { word, word, word}; var getFromDb = function(index) { db.get(searchVariation[index], function (err, value) { if(err) { if(index < searchVariation.length) getFromDb(index++) else func(); } else { func(value) } } } getFromDb(0); }
באוסף searchVariation שמתי רשימה של אותה מילה אבל הכוונה לעשות וריאציות שונות. הבדיקה עליהם תופעל לפי סדר (רק במקרה כישלון של הראשון תתבצע בדיקה של השני).
אם עצם הכנת הוריאציות עולה ביצועים אתה יכול לוותר על רשימה אבל לעשות פונקציה שמקבלת את המקור ורשימה של מה שנוסה כבר ובודקת אם יש מה לנסות עוד.
במידה ויש לך וריאציות עם אותו עדיפות הכי טוב זה לשלוח אסינכרוני ו"כל הקודם זוכה" ככה אתה מרויח את מעלת הJS.
עוד לא ישנתי משבת.. אז עוד אתעמק בתשובתך
בנתיים מה שעולה לי מיד
הקוד נראה בנתיים כך
exports.getNikudEvent = function ( words, ee ) {
var nikudim = [];
if( typeof words == 'string' ) words = words.split();
var cnt = -1
async.each(words, function(word, next){
db.get(word,function (err, value) {
cnt++
if (err) {
console.log('Ooops cnot get nikud for: ', word) ;
}
if (value) value = value.split(',');
nikudim.push(value);
next();
});
}
,
function() {
ee.emit("sendAjax", nikudim);
}
);
};
app.post('/getajax', function( req , res) {
var words = req.body.sendWord;
var indexElm = req.body.indexElm;
db.getNikudEvent(words, ee);
ee.once("sendAjax", function (nikudim) {
var obj = { nikudim: nikudim, indexElm: indexElm };
res.send(obj);
});
});
אין לי מילים להודות לך!!
פורסם במקור בפורום CODE613 ב06/09/2015 14:25 (+03:00)
@דוד ל.ט.
לא הבנתי כל כך.
מה הבעיה בסגנון הזה:app.post("/", function (req, res) { getDataFromDB('word', res); }); function getDataFromDB(word, res) { db.get(word, function (err, value) { if (err) res.status(404).send('Not found'); res.send(value); }); }
נסיתי ככה ועבד מצוין
הבעיה היא שאני משתמש בעוד נתונים שבאים ב-req והתווספו עוד ועוד ארגומנטים
אז כבר היה עדיף להעביר גם את req וגם את res, אבל אז כבר לא נשאר הגיון לחלוקה
ככה יש קובץ app וקובץ DBmanual
(זה גם עונה על השאלה השניה שלך)
פשוט צריך להתרגל, אבל זה דומה
את המשך הפונקציה אני מכניס לתוך .on
ובפונקציה שמחפשת את המילה במקום return כותבים event.emit...
הא, והיתה סיבה נוספת לבלגן
הpost מקבל קטע שלם ואני מריץ לולאה על כל מילה ואוגר ואז מחזיר
עכשיו אני מסתבך במיוחד
אם המילה לא נמצאת במילון, אני מחפש אותה בעוד ווירואציות
לדוגמא אם לא מוצא "לדעת" אז הוא מזהה שלמ"ד זו אות צמוד ומחפש "דעת" ואז יודע לחבר, יש המון אפשרויות כאלו, ובשביל זה צריך לבדוק הרבה פעמים, כל אפשרות אם נמצאת במילון ואם לא להמשיך לנסיונות הבאים.
ובכל זה לבצע באי סינכרוני וקולבקים.
:roll:
אבל יש פתרונות, אין ספק.
פורסם במקור בפורום CODE613 ב06/09/2015 12:19 (+03:00)
http://expressjs.com/guide/routing.html
אבל זה החלק השולי
get.post זו הוראה לשרת ליצור כתובת
לכתובת הזו ajax שולח את הבקשה ומקבל תשובה.
עכשיו כש-ajax בקלינט פונה לשרת, השרת מבצע פעולה על הנשלח ומחזיר
ואם הפעולה הזאת קוראת לפעולה אחרת אי סינכרונית, הפונקציה נגמרת ולא מחזירה כלום לקלינט שממתין לתשובה.
בסוף, אחרי ים זמן, ועזרה מאנשים טובים
אחרי קבלת הדאטה מהקלינט, אני קורא לפונקציה האי סינכרונית ומיד מקים האזנה לארוע (כשהארוע יקרה תישלח תשובה), והפונקציה האי סינכרונית מפעילה את הארוע הזה.
זהו, אני קירח....
פורסם במקור בפורום CODE613 ב06/09/2015 10:56 (+03:00)
אכן js היא שפה מאוד שונה משפות אחרות והמבנה שלה נוח מאוד לעבודה אסינכרונית, צריך ללמוד לחיות עם זה ולא להילחם בזה.
תחשוב איך זה כשאני צריך לחפש מילה ואם לא מוצא לנסות בוירואציות שונות, וכל זה באסינכרוני :shock:
פורסם במקור בפורום CODE613 ב06/09/2015 09:18 (+03:00)
אכן js היא שפה מאוד שונה משפות אחרות והמבנה שלה נוח מאוד לעבודה אסינכרונית, צריך ללמוד לחיות עם זה ולא להילחם בזה.
אני ממתין לך בסבלנות
ואתה בורח אחרי שורה אחת?
פורסם במקור בפורום CODE613 ב06/09/2015 03:01 (+03:00)
כן, אני הולך לעשות פה נחת לכמה עם ההסתבכות ב-JS..
(אם כי, הופתעתי לגלות שעל השפה שהם 'לא יודעים', לא אוהבים ולא מסתדרים - הם יודעים יותר מכל מה שאני יודע על תכנות בכלל)
function getDataFromDB(word) {
db.get(word, function (err, value) {
if (err) return console.log('Ooops! cnot get nikud', err); // likely the key was not found
return value;
});
}
עד כאן ממש נפלא
מעתיקים מהתיעוד ורואים שהערך נרשם בקונסול אז 'הכל עובד', ורצים להדפיס מודעות על קורס מתקדם....
הצרה היא שבעולם האמיתי פתאום רוצים לקבל את הדאטה חזרה לפונקציה הקוראת וכש-return מחזיר את הערך הפונקציה הקוראת כבר לא קיימת!
אז בשביל יש את הקול-בק.
אז מה עושים כשהפונקציה הקוראת זה get.post בסרבר שמקבל בקשת ajax שבנתיים מחזירה undefined לקלינט, שלא לדבר אם מפעילים את db.get בלולאה..
??
פורסם במקור בפורום CODE613 ב03/09/2015 23:08 (+03:00)
@דוד ל.ט.
function myModule() { ... } var myModule = new myModule(); //creating the instanceמה זה עושה ??
מה עושה שמכניסים את אותו משתנה לתוכו?
כשכותבים new לפני קריאה לפונקציה, אז:
- במידה והפונקציה מחזירה אובייקט (לא פרימיטיבי כטקסט ומספר כלומר כזה שהלוג שלו מיוצג עם סוגריים {}), אז הוא מוחזר למשתנה.
- במידה ואיננה מחזירה אובייקט (או שאיננה מחזירה כלום או טיפוס פרימיטיבי) אז נוצר אובייקט חדש שמהווה "קרקע" (בתכנותית: מופע, instance) לthis שבפונקציה. בלי ה"קרקע" הזו הפונקציה הנקראת "דורכת" על "קרקע" הפונקציה הקוראת.
הדגמה:
function func() { this.a = "variable "; return "function result..."; } var resultWithoutNew = func(); console.log(resultWithoutNew); //function result... console.log(a); // variable console.log(resultWithoutNew.a); // undefined a = 123; var resultWithNew = new func(); console.log(resultWithNew); // { a: 'variable ' } console.log(a); // 123 console.log(resultWithNew.a); // variable
הnew מאפשר לתת "סקופ" חדש למה שהפונקציה מחזירה וככה ליצור מופעים שונים של אותו מחלקה-אב טיפוס על מאפייניו והפונקציות שלו.
לא מבין [כמעט] כלום
this.a = "variable ";
שווה ל
func.a = "variable ";
?
איך
console.log(a); // variable
a = 123;
ממתי יש משתנה a?
הרי a הוא רק תכונה (property) של func והעתקים ממנו?!
var resultWithoutNew = func();
אם כן אני צודק שיש 3 'רמות' של העברה בין פונקציה לפונקציה
resultWithNew = func();
resultWithNew = new func();
resultWithNew = func;
אם משתמשים באפשרות 3, ואז שעכשיו מכיל בתוכו
this.a = "variable ";
מי שם ה-this ?
סליחה על ההתקפה ותודה על הסבלנות
פורסם במקור בפורום CODE613 ב18/09/2015 16:48 (+03:00)
עכשיו עולה בדעתי
שכל המודול הרי קבצי JS פתוחים, אז ה-ide פשוט טוען אותם, כמו כשאני מוסיף פונקציות ומשתמש באלו שכתבתי קודם שהוא מכיר אותם.
פורסם במקור בפורום CODE613 ב06/09/2015 21:41 (+03:00)
@דוד ל.ט.
תלונתו היא שאתה ניגש לvalur בלי לבדוק קודם שהerror ריק (אם תוסיף if (!err) אזי הוא ישתוק כנראה), אבל נשגב מבינתי איך ה"חוזה" הזה מוכר לIDE.
עכשיו מצאתי איך הפונקציה עובדת
באמת עם try (מושג חדש שלא הכרתי עד שהכרת לי)
LevelUP.prototype.get = function (key_, options, callback) {
var self = this
, key
callback = getCallback(options, callback)
if (maybeError(this, options, callback))
return
if (key_ === null || key_ === undefined || 'function' !== typeof callback)
return readError(this
, 'get() requires key and callback arguments', callback)
options = util.getOptions(options)
key = this._codec.encodeKey(key_, options)
options.asBuffer = this._codec.valueAsBuffer(options)
this.db.get(key, options, function (err, value) {
if (err) {
if ((/notfound/i).test(err) || err.notFound) {
err = new NotFoundError(
'Key not found in database [' + key_ + ']', err)
} else {
err = new ReadError(err)
}
return dispatchError(self, err, callback)
}
if (callback) {
try {
value = self._codec.decodeValue(value, options)
} catch (e) {
return callback(new EncodingError(e))
}
callback(null, value)
}
})
}
פורסם במקור בפורום CODE613 ב06/09/2015 21:32 (+03:00)
אז עוד שאלה על JS......
לשאלה הזו יש הרבה חברים
פורסם במקור בפורום CODE613 ב06/09/2015 11:21 (+03:00)