Kaip paaiškinti atgalines žinutes paprastu anglų kalba? Kaip jie skiriasi nuo vienos funkcijos iš kitos funkcijos skambinimo?

Kaip paaiškinti atgalines žinutes paprastu anglų kalba? Kaip jie skiriasi nuo vienos funkcijos skambučio iš kitos funkcijos, atsižvelgiant į tam tikrą kontekstą iš skambinimo funkcijos? Kaip paaiškinti savo galią pradedantiesiems programuotojams?

279
07 марта '12 в 8:25 2012-03-07 08:25 nustatytas „ Yahoo-Me “ kovo 12 d. 12:25 2012-03-07 08:25
@ 32 atsakymai
  • 1
  • 2

Dažnai programa turi atlikti įvairias funkcijas pagal savo kontekstą / būseną. Tam mes naudojame kintamąjį, kuriame mes išsaugosime informaciją apie pavadintą funkciją. Pagal savo poreikį programa nustatys šį kintamąjį su informacija apie iškviestą funkciją ir paskambins funkcijai naudojant tą patį kintamąjį.

Toliau pateiktame javascript yra pavyzdys. Čia mes naudojame metodo argumentą kaip kintamąjį, kuriame saugome informaciją apie funkciją.

 function processArray(arr, callback) { var resultArr = new Array(); for (var i = arr.length-1; i >= 0; i--) resultArr[i] = callback(arr[i]); return resultArr; } var arr = [1, 2, 3, 4]; var arrReturned = processArray(arr, function(arg) {return arg * -1;}); // arrReturned would be [-1, -2, -3, -4] 
97
10 марта '12 в 11:17 2012-03-10 11:17 atsakymas pateikiamas Niraj Nawanit kovo 10 d. 12 val. 11:17 2012-03-10 11:17

Aš stengsiuosi, kad jis būtų miręs. "Atgalinis atgalinis ryšys" - tai bet kuri kita funkcija, kurią vadina kita funkcija kaip pirmoji funkcija. Daug kartų „atšaukimas“ yra funkcija, kuri vadinama, kai kas nors įvyksta. Tai gali būti vadinama „įvykiu“ programuojant.

Įsivaizduokite šį scenarijų: galite tikėtis paketo per kelias dienas. Paketas yra dovana jūsų artimui. Todėl, kai tik gausite paketą, norite, kad jis vyktų į kaimynus. Jūs esate iš miesto, todėl paliekate nurodymus savo sutuoktiniui.

Jūs galite pasakyti jiems, kad jie gautų paketą ir pristatytų ją kaimynams. Jei jūsų sutuoktinis buvo toks kvailas kaip kompiuteris, jie sėdėtų prie durų ir laukė paketo, kol jis ateis (NEI KLAUSIMA), o tada, kai ateis, jie perduos savo kaimynams. Bet yra geresnis būdas. Papasakokite savo sutuoktiniui, kad gavę paketą, jie turi jį pateikti savo kaimynams. Tada jie gali normaliai gyventi, kol jie gauna paketą.

Mūsų pavyzdyje paketo priėmimas yra "įvykis", o jo pristatymas į kaimynus yra "atgalinis". Jūsų sutuoktinis „vadovauja“ jūsų nurodymams perkelti paketą tik po to, kai atvyksta paketas. Daug geriau!

Toks mąstymas akivaizdus kasdieniame gyvenime, tačiau kompiuteriai neturi to paties sveiko proto. Pagalvokite, kaip programuotojai paprastai rašo failą:

 fileObject = open(file) # now that we have WAITED for the file to open, we can write to it fileObject.write("We are writing to the file.") # now we can continue doing the other, totally unrelated things our program does 

Čia laukiame, kol atidarysime failą, kol mes jį parašysime. Tai „blokuoja“ vykdymo srautą, o mūsų programa negali atlikti jokių kitų veiksmų, kurių gali prireikti! Ką daryti, jei galėtume tai padaryti:

 # we pass writeToFile (A CALLBACK FUNCTION!) to the open function fileObject = open(file, writeToFile) # execution continues flowing -- we don't wait for the file to be opened # ONCE the file is opened we write to it, but while we wait WE CAN DO OTHER THINGS! 

Pasirodo, kad tai darome su kai kuriomis kalbomis ir sistemomis. Tai gana kietas! Išbandykite „ Node.js“, kad gautumėte tikrą praktiką.

415
11 марта '12 в 7:24 2012-03-11 07:24 Atsakymą pateikė Josh Imhoff kovo 11 d. 12 val. 2012-03-11 07:24

Kaip paaiškinti atgalines žinutes paprastu anglų kalba?

Paprastai anglų kalba, atgalinio ryšio funkcija yra panaši į Darbuotoją, kuris „iškviečia“ savo vadovybę, kai baigė užduotį .

Kaip jie skiriasi nuo to, kad skambinama viena funkcija iš kitos funkcijos, atsižvelgiant į tam tikrą kontekstą iš skambinimo funkcijos?

Tiesa, kad skambinate funkcijai iš kitos funkcijos, tačiau raktas yra tai, kad atgalinis ryšys yra traktuojamas kaip objektas, todėl galite keisti, kurią funkciją skambinti pagal sistemos būklę (pvz., Strategijos dizaino modelis).

Kaip jų gebėjimas paaiškinti pradedantiesiems programuotojams?

Atšaukimų galia gali būti lengvai matoma AJAX stiliaus svetainėse, kuriose reikia gauti duomenis iš serverio. Naujų duomenų įkėlimas gali užtrukti. Be atšaukimo, visa vartotojo sąsaja užšąla, kai įkeliami nauji duomenys, arba turite atnaujinti visą puslapį, o ne tik jo dalį. Su atgaliniu ryšiu galite įkelti „dabar įkeltą“ vaizdą ir jį pakeisti naujais duomenimis po to, kai jis atsisiunčiamas.

Keletas kodo be atgalinio ryšio:

 function grabAndFreeze() { showNowLoading(true); var jsondata = getData('http://yourserver.com/data/messages.json');  processData(jsondata); showNowLoading(false); do_other_stuff(); // not called until data fully downloaded } function processData(jsondata) { // do something with the data var count = jsondata.results ? jsondata.results.length : 0; $('#counter_messages').text(['Fetched', count, 'new items'].join(' ')); $('#results_messages').html(jsondata.results || '(no new messages)'); } 

Su atšaukimu:

Čia yra pavyzdys su atgaliniu ryšiu naudojant jQuery getJSON :

 function processDataCB(jsondata) { // callback: update UI with results showNowLoading(false); var count = jsondata.results ? jsondata.results.length : 0; $('#counter_messages').text(['Fetched', count, 'new items'].join(' ')); $('#results_messages').html(jsondata.results || '(no new messages)'); } function grabAndGo() { // and don't freeze showNowLoading(true); $('#results_messages').html(now_loading_image); $.getJSON("http://yourserver.com/data/messages.json", processDataCB);  do_other_stuff(); // called immediately } 

Uždaryta:

Dažnai atgalinis ryšys turi pasiekti state iš skambučio funkcijos, naudodamas closure , kuris yra panašus į Darbuotoją , kuriam reikalinga informacija iš vadovo, kad jis galėtų užbaigti užduotį . Jei norite sukurti closure funkciją, galite įterpti funkciją, kad ji peržiūrėtų skambučio kontekste esančius duomenis:

  function grab(dtable, cb) { if (null == dtable) { dtable = "messages"; } var uiElem = "_" + dtable; showNowLoading(true, dtable); $('#results' + uiElem).html(now_loading_image); $.getJSON("http://yourserver.com/user/"+dtable+".json", cb || function (jsondata) { // Using a closure: can "see" dtable argument and uiElem variables above. var count = jsondata.results ? jsondata.results.length : 0, counterMsg = ['Fetched', count, 'new', dtable].join(' '), // no new chatters/messages/etc defaultResultsMsg = ['(no new ', dtable, ')'].join(''); showNowLoading(false, dtable); $('#counter' + uiElem).text(counterMsg); $('#results'+ uiElem).html(jsondata.results || defaultResultsMsg); });  do_other_stuff(); // called immediately } 

Naudoti:

 // update results_chatters when chatters.json data is downloaded: grab("chatters"); // update results_messages when messages.json data is downloaded grab("messages"); // call myCallback(jsondata) when "history.json" data is loaded: grab("history", myCallback); 

Uždarymas

Galiausiai čia pateikiamas Douglas Crockford closure apibrėžimas:

Funkcijos gali būti apibrėžtos kitose funkcijose. Vidinė funkcija turi prieigą prie vars ir išorinių funkcijų parametrų. Jei nuoroda į vidinę funkciją yra išsaugota (pavyzdžiui, kaip atgalinio ryšio funkcija), taip pat išsaugomos išorinės vars funkcijos.

Taip pat žiūrėkite:

74
12 марта '12 в 7:12 2012-03-12 07:12 atsakymą pateikė vartotojo508994 „ Kovo 12 d., 12 d., 07:12 am 2012-03-12 07:12

Aš pasibaisėtinai matau tiek daug protingų žmonių, kurie negalėjo pabrėžti realybės, kad žodis „atgalinis“ buvo naudojamas dviem nenuosekliais būdais.

Abu metodai apima funkcijos nustatymą perduodant papildomą funkciją (funkcijos apibrėžimą, anoniminį arba pavadintą) esamai funkcijai. tai yra.

 customizableFunc(customFunctionality) 

Jei vartotojo funkcijos yra tiesiog prijungtos prie kodo bloko, konfigūravote šią funkciją.

  customizableFucn(customFunctionality) { var data = doSomthing(); customFunctionality(data); ... } 

Nors tokios įgyvendintos funkcijos dažnai vadinamos „atšaukimu“, nėra nieko panašaus. Labai akivaizdus pavyzdys yra „išankstinis“ metodas, kuriame pasirinkta funkcija teikiama kaip argumentas, taikomas kiekvienam masyvo elementui masyvo modifikavimui.

Bet tai iš esmės skiriasi nuo atgalinio ryšio funkcijų, naudojamų asinchroniniam programavimui , kaip ir AJAX arba node.js, arba tiesiog priskirti funkcionalumą vartotojo sąveikos įvykiams (pvz., Pelės paspaudimams) .Šiuo atveju visa idėja yra laukti. įvykius prieš atliekant pasirinktines funkcijas. Tai akivaizdu vartotojo sąveikos atveju, tačiau taip pat svarbu įvesties / išvesties (įvesties / išvesties) procesuose, kurie gali užtrukti, pvz., Skaityti failus iš disko. Būtent čia terminas „atšaukimas“ turi aiškiausią reikšmę. Kai tik prasideda įvesties / išvesties procesas (pavyzdžiui, prašo skaityti failą iš disko ar serverio, kad būtų grąžinti duomenys iš HTTP užklausos), asinchroninė programa nelaukia, kol ji baigsis. Jis gali atlikti kitas užduotis, numatytas kitą dieną, ir atsakyti tik su vartotojo nustatytomis funkcijomis po to, kai jam bus pranešta apie failo arba HTTP užklausos skaitymo užbaigimą (arba kad jis nepavyko) ir kad duomenys yra prieinami vartotojo nustatytoms funkcijoms. Taip galite paskambinti telefonu ir palikti savo „atgalinio ryšio“ numerį, kad jie galėtų paskambinti jums, kai kas nors gali jums grįžti. Tai geriau nei kabinti ant linijos, tiems, kurie žino, kiek laiko ir negali daryti kitų dalykų.

Asinchroninis naudojimas iš esmės apima tam tikrą būdą klausytis norimo įvykio (pavyzdžiui, užbaigti I / O procesą), kad, kai tai atsitiks (ir tik tada, kai tai atsitiks), vykdoma pasirinktinė atgalinio ryšio funkcija. Akivaizdu AJAX pavyzdžiu, kai duomenys faktiškai gaunami iš serverio, „atgalinio ryšio“ funkcija pradeda naudoti šiuos duomenis modifikuoti DOM ir todėl redaguoja naršyklės >

Pakartokite. Kai kurie žmonės naudoja žodį „atgalinio ryšio“, kad gal ÷ tų nurodyti bet kurias vartotojo nustatytas funkcijas, kurios gali būti įvestos į esamą funkciją kaip argumentas. Tačiau, bent jau man, tinkamiausias šio žodžio panaudojimas yra tai, kad įvestas atgalinio ryšio funkcija naudojama asinchroniškai - vykdyti tik tada, kai įvykis įvyksta, kai tikisi gauti pranešimą.

26
08 окт. Robert Polevoi atsakymas 08 spalis 2015-10-08 21:36 '15, 21:36, 2015-10-08 21:36

Kitaip nei programuotojas, atgalinis atšaukimas yra mėginio užpildymas programoje.

Bendras daugelio popierinių formų dalykas yra „Asmuo, kuris turėtų skambinti avarijos atveju“. Yra tuščia eilutė. Parašote vardą ir telefono numerį. Įvykus avarijai, šis asmuo gauna skambutį.

  • Kiekvienas gauna tą pačią tuščią formą, bet
  • Kiekvienas gali parašyti kitą pagalbos tarnybos numerį.

Tai raktas. Formos (kodo, paprastai kito asmens) nekeičiate. Tačiau galite užpildyti trūkstamą informaciją (savo numerį).

1 pavyzdys:

Atšaukimai naudojami kaip pasirinktiniai metodai, galbūt pridedant / keičiant programos elgesį. Pavyzdžiui, paimkite tam tikrą C kodą, kuris atlieka funkciją, bet nežino, kaip spausdinti išvestį. Viskas, ką jis gali padaryti, yra padaryti eilutę. Kai jis bando suprasti, ką daryti su eilute, jis mato tuščią eilutę. Tačiau programuotojas davė jums erdvę, kad galėtumėte parašyti atgalinį ryšį!

Šiame pavyzdyje nenaudojate pieštuko, kad užpildytumėte popieriaus lapo vietą, naudosite funkciją set_print_callback(the_callback) .

  • Tinklo kintamasis modulyje / kode yra tuščia eilutė,
  • set_print_callback yra paketas,
  • ir „ the_callback yra jūsų informacija, kurią užpildote.

Dabar jūs užpildėte šią tuščią eilutę programoje. Kai jis turi spausdinti išvestį, jis žiūri į šią tuščią eilutę ir laikysis ten pateiktų nurodymų (t. Y. Skambinkite ten esančia funkcija). Praktiškai tai leidžia spausdinti ekrane, žurnalo faile, spausdintuve, per tinklo ryšį arba bet kurį jų derinį. Jūs užpildėte atotrūkį su tuo, ko norite.

2 pavyzdys:

Kai jums sakoma, kad jums reikia skambinti pagalbos numeriu, eikite ir perskaitykite tai, kas parašyta popieriaus formoje, ir paskambinkite skaitytu numeriu. Jei ši eilutė tuščia, nieko nebus padaryta.

Gui programavimas veikia taip pat. Paspaudus mygtuką, programa turi išsiaiškinti, ką daryti toliau. Jis eina ir ieško atgalinio ryšio. Šis atšaukimas yra erdvėje, pažymėtoje „Tai, ką darote paspaudus mygtuką“

Dauguma IDE automatiškai užpildys jums skirtą vietą (parašykite pagrindinį metodą), kai to paprašysite (pvz., button1_clicked ). Tačiau šis atotrūkis gali turėti bet kokį metodą, kurį galite gerai nuryti. Jei šį atšaukimo vardą butter_the_biscuits teisingoje vietoje, galite skambinti „ run_computations arba butter_the_biscuits metodu. „555-555-1212“ galite įdėti į skubios pagalbos tarnybos numerį. Tai nėra labai prasminga, bet tai leidžiama.


Galutinė pastaba: ši tuščia eilutė, kurią užpildote atgaline data? Jis gali būti ištrintas ir perrašytas savo nuožiūra. (ar jums reikia kito klausimo, bet tai yra jų galios dalis)

23
12 марта '12 в 20:13 2012-03-12 20:13 atsakymą pateikė JoeyG kovo 12 d. 12 val. 2012-03-12 20:13

Johnny'ui reikia programuotojui staplerio, todėl jis eina į biuro tiekimo skyrių ir prašo jo, užpildęs prašymo formą, jis gali stovėti ten arba laukti, kol sekretorius išnagrinės sandėlio raktą (pvz., Blokuoja funkcijų skambutį) arba eina kažką kito .

Kadangi paprastai užtrunka laiko, Johnny kartu su prašymo forma užsirašo pastabą, prašydama paskambinti jam, kai segiklis yra pasiruošęs būti išsiųstas, todėl jis gali eiti kažką kito, pvz.

19
11 марта '12 в 17:56 2012-03-11 17:56 atsakymas perduodamas kovo 11 d., 12 d., 5:56 val. 2012-03-11 17:56

Visada geriau pradėti su pavyzdžiu :).

Tarkime, kad turite du A ir B modulius.

Norite, kad modulis A būtų informuotas, kai B modulyje įvyksta įvykis / būklė. Tačiau modulis B neturi idėjos apie jūsų modulį A. Viskas, ką ji žino, yra konkrečios funkcijos adresas (modulis A) per funkcijų žymeklį kurį jam suteikia A modulis.

Taigi, dabar B turi būti „Atgal“ į A modulį, kai tam tikras įvykis / būklė atsiranda su funkcijų rodykle. A gali atlikti papildomą apdorojimą atgalinio ryšio funkcijos viduje.

*) Aiškus pranašumas yra tai, kad jūs sutraukiate viską, kas susiję su A moduliu iš B modulio. B modulis neturi rūpintis, kas / kas modulis yra A.

18
07 марта '12 в 8:44 2012-03-07 08:44 atsakymą pateikė Gargi Srinivas kovo 12 d. 12 val. 8:44 2012-03-07 08:44

Įsivaizduokite, kad jums reikia funkcijos, kuri sugrąžins 10 kvadratą, kad rašytumėte funkciją:

 function tenSquared() {return 10*10;} 

Vėliau jums reikės 9 kvadratų, kad parašytumėte kitą funkciją:

 function nineSquared() {return 9*9;} 

Galų gale jūs visi pakeisite bendrą funkciją:

 function square(x) {return x*x;} 

Tikslus mąstymas naudojamas atšaukimams. Turite funkciją, kuri daro kažką ir kada atliekami doA skambučiai:

 function computeA(){ ... doA(result); } 

Vėliau norite tą pačią funkciją skambinti doB, vietoj to galite kopijuoti visą funkciją:

 function computeB(){ ... doB(result); } 

Arba galite perduoti atgalinio ryšio funkciją kaip kintamąjį ir tik vieną kartą atlikti šią funkciją:

 function compute(callback){ ... callback(result); } 

Tada jums reikia paskambinti skaičiuoti (doA) ir apskaičiuoti (doB).

Be supaprastinimo kodo, jis leidžia asinchroniniam kodui pranešti, kad jis nutrauktas, kai baigsite skambinti savo savavališka funkcija, tokiu pat būdu, kaip skambinate žmogui telefonu ir palikite atgalinį numerį.

13
11 марта '12 в 7:00 2012-03-11 07:00 atsakymą pateikė „ Brian Nickel “ kovo 11 d. 12 val. 2012-03-11 07:00

Jūs jaučiatės blogai, todėl kreipkitės į gydytoją. Jis jus išnagrinėja ir nustato, kad jums reikia vaisto. Jis nurodo kai kuriuos vaistus ir kviečia receptą vietinėje vaistinėje. Jūs einate namo. Vėliau jūsų vaistinė kviečia pranešti, kad Jūsų receptas yra paruoštas. Jūs einate ir pasiimti.

10
11 марта '12 в 6:33 2012-03-11 06:33 atsakymas pateikiamas įvaizdžiui kovo 11 d. 12 val. 2012-03-11 06:33

Čia aprašomi du dalykai: kaip veikia atgalinis ryšys (perduodama funkcija, kurią galima vadinti be jokio žinojimo apie jo kontekstą), kitas naudojamas (įvykio apdorojimas yra asinchroninis).

Kitų atsakymų metu naudotas laukimo laukimo analogiškumas yra naudingas abiem. Kompiuterio programoje pasakytumėte, kad kompiuteris laukia paketo. Paprastai jis būtų sėdėjęs ten ir laukė (ir nieko nedarė), kol paketas atvyko, galbūt be galo, jei ji neatvyko. Žmonėms tai skamba kvailai, bet be papildomų priemonių kompiuteriui visiškai natūralu.

Dabar jūsų atgalinis skambutis bus varpas. Jūs teikiate siuntų tarnybą, kad praneštumėte apie sklypo atvykimą, kad jie nežinotų, kur (net jei) esate namuose arba kaip veikia skambutis. (Pavyzdžiui, kai kurie „varpai“ faktiškai siunčia skambutį.) Kadangi jūs suteikėte „atgalinio ryšio funkciją“, kurią galite „skambinti“ bet kuriuo metu, be konteksto, dabar galite nustoti sėdėti prie priekinės verandos ir „tvarkyti įvykį“ (pakuotės atvykimas). ) bet kuriuo metu.

7
11 марта '12 в 12:05 2012-03-11 12:05 atsakymą pateikė „ Hanno Fietz “ kovo 12 d. 12:05 2012-03-03 12:05

Įsivaizduokite, kad draugas palieka jūsų namus, ir jūs jai sakote: „Skambink man, kai grįšite namo, todėl žinau, kad saugiai atvykote“; tai yra (pažodžiui) atšaukimas. Tai yra atgalinio ryšio funkcija, nepriklausomai nuo kalbos. Norite, kad procedūra būtų perduota jums, kai ji atliks tam tikrą užduotį, todėl suteikiate jai funkciją, kuri bus naudojama jums paskambinti.

Pavyzdžiui, „Python“

 grabDBValue( (lambda x: passValueToGUIWindow(x) )) 

grabDBValue gali būti parašyta tik tam, kad gautumėte vertę iš duomenų bazės, ir tada galite nurodyti, ką iš tikrųjų daryti su verte, todėl ji priima funkciją. Jūs nežinote, kada grabDBValue grįš, bet jei tai atsitiks, jūs žinote, ko norite. Čia aš perduodu anoniminę funkciją (arba lambda), kuri siunčia vertę į GUI >

 grabDBValue( (lambda x: passToLogger(x) )) 

Atšaukimai veikia gerai tomis kalbomis, kuriose funkcijos yra pirmos klasės vertės, kaip ir įprastiniai sveikieji skaičiai, simbolių eilutės, boolean ir kt. „C“ galite „perduoti“ funkciją aplinkui, perduodant žymeklį aplink jį, o skambintojas gali jį naudoti; „Java“ skambintojas paprašys statinio tipo tam tikro tipo su konkrečiu metodo pavadinimu, nes nėra klasių funkcijų („iš tikrųjų“); ir daugumoje kitų dinamiškų kalbų galite tiesiog perduoti funkciją paprasta sintaksė.

Protip: