Kaip grąžinti atsakymą iš asinchroninio skambučio?

Turiu foo funkciją, kuri pateikia Ajax užklausą. Kaip grąžinti atsakymą iš foo ?

Bandžiau grąžinti vertę iš success atšaukimo ir taip pat priskirti atsakymą į vietinį kintamąjį funkcijos viduje ir grąžinti jį, tačiau nė vienas iš šių metodų neatsako.

 function foo() { var result; $.ajax({ url: '...', success: function(response) { result = response; // return response; // <- I tried that one as well } }); return result; } var result = foo(); // It always ends up being `undefined`. 
4687
08 янв. „Felix Kling“ rinkosi sausio 08 2013-01-08 20:06 '13, 20:06, 2013-01-08 20:06
@ 39 atsakymų
  • 1
  • 2

Štai pavyzdys, kuris veikia:

 const validateName = async userName => { const url = "abc/xyz"; try { const response = await axios.get(url); return response.data } catch (err) { return false; } }; validateName("user") .then(data => console.log(data)) .catch(reason => console.log(reason.message)) 
6
13 июля '18 в 0:48 2018-07-13 00:48 Atsakymą pateikė Alex Montoya liepos 13 d. 18 val. 0:48 2018-07-13 00:48

Naudojant pažadus, paprastas sprendimas būtų:

 function asyncFunc(options) { return new Promise(function (resolve, reject) { $.ajax(options).done(resolve).fail(reject); }); } asyncFunc({ url: '/api/users/create', type: 'post', dataType: 'json', data: { action: value } }).then( function successHandler(data) { // callback console.log(data); } ).catch(function errorHandler(error) { // error console.log(error); }); 
2
26 июля '18 в 9:34 2018-07-26 09:34 atsakymą Srinivas davė liepos 26 d. 18 d. 9:34 am 2018-07-26 09:34

Čia pateikiami du būdai, kaip tvarkyti asinchroninių funkcijų užklausas:

  1. Atšaukimai
  2. Pažadai (mano mėgstamiausia, aseptiškai su asinchroniniu / laukiančiu )

Pažvelkime į pavyzdžius:

Atšaukimai

Idėja yra ta, kad jums reikia perduoti atgalinio ryšio funkciją kaip argumentą savo asinchroninei funkcijai. Šis atšaukimas bus iškviestas, kai tik asinchroninė funkcija bus paruošta grąžinti naudingąją apkrovą. Naudingoji apkrova siunčiama atgal kaip atgalinio ryšio funkcijos argumentas. Pavyzdžio kodą galima perrašyti taip:

  const foo = () => { return new Promise((resolve, reject) => { $.ajax({ url: '...', success: (response) => { resolve(response); } }); }); } foo().then((response) => { // Do something with response here. }); 

Jei norite, galite naudoti async / wait, kad šiek tiek išlygintumėte kodo struktūrą ir kad ji atrodytų sinchroniškai:

1
20 сент. atsakymą pateikė Oleksii Trekhleb 20 sep . 2018-09-20 13:06 '18, 13:06 val. 2018-09-20 13:06
 function foo() { var result; $.ajax({ url: '...', async: false, success: function(response) { result = response; // return response; // <- I tried that one as well } }); return result; } var result = foo(); // now your problem has been resolved, but assure that async is @Deprecated. 
0
05 мая '18 в 15:44 2018-05-05 15:44 atsakė Dharmendrasin Chudasama gegužės 05'18 val. 15:44 2018-05-05 15:44

Geriausias atsakymas į šį klausimą yra „ Promise .

 function ajax(method, url, params) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); xhr.onload = function() { resolve(this.responseText); }; xhr.onerror = reject; xhr.open(method, url); xhr.send(params); }); } ajax("GET", "/test", "acrive=1").then(function(result) { // Code depending on result }) .catch(function() { // An error occurred }); 

problemą

Aš kurį laiką naudoju šį sprendimą, kol supratau, kad senose naršyklėse yra klaida:

 Uncaught ReferenceError: Promise is not defined 

Taigi nusprendžiau įgyvendinti savo „Promise“ klasę ES3 virš js kompiliatorių, jei jis nėra apibrėžtas.

 if(typeof Promise === "undefined"){ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Promise = function () { function Promise(main) { var _this = this; _classCallCheck(this, Promise); this.value = undefined; this.callbacks = []; var resolve = function resolve(resolveValue) { _this.value = resolveValue; _this.triggerCallbacks(); }; var reject = function reject(rejectValue) { _this.value = rejectValue; _this.triggerCallbacks(); }; main(resolve, reject); } Promise.prototype.then = function then(cb) { var _this2 = this; var next = new Promise(function (resolve) { _this2.callbacks.push(function (x) { return resolve(cb(x)); }); }); return next; }; Promise.prototype.catch = function catch_(cb) { var _this2 = this; var next = new Promise(function (reject) { _this2.callbacks.push(function (x) { return reject(cb(x)); }); }); return next; }; Promise.prototype.triggerCallbacks = function triggerCallbacks() { var _this3 = this; this.callbacks.forEach(function (cb) { cb(_this3.value); }); }; return Promise; }(); } 
0
07 дек. Amir Forsati atsakymas 07 Dec 2018-12-07 17:10 '18 at 5:10 pm 2018-12-07 17:10

Paprastas kodo pavyzdys, kaip konvertuoti XHR mazge į async-wait

 var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; var xhttp = new XMLHttpRequest(); function xhrWrapWithPromise() { return new Promise((resolve, reject) => { xhttp.onreadystatechange = function() { if (this.readyState == 4) { if (this.status == 200) { resolve(this.responseText); } else { reject(new Error("Couldn't feth data finally")); } } }; xhttp.open("GET", "https://www.w3schools.com/xml/xmlhttp_info.txt", true); xhttp.send(); }); } //We need to wrap await in Async function so and anonymous IIFE here (async _ => { try { let result = await xhrWrapWithPromise(); console.log(result); } catch (error) { console.log(error); } })(); 
-2
02 дек. Atsakymas pateikiamas Sumer 02 Dec 2018-12-02 15:41 '18, 15:41 pm 2018-12-02 15:41

mazge galite naudoti deasync: https://www.npmjs.com/package/deasync

 var deasync = require('deasync'); var cp = require('child_process'); var exec = deasync(cp.exec); // output result of ls -la try{ console.log(exec('ls -la')); } catch(err){ console.log(err); } // done is printed last, as supposed, with cp.exec wrapped in deasync; first without. console.log('done'); 
-5
15 февр. Thomas Grainger atsakymas vasario 15 d 2018-02-15 14:10 '18, 14:10 pm 2018-02-15 14:10

Trūksta funkcijos išvesties linijos

 <!DOCTYPE html> <html> <title>Web Page Design</title> <head> <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script> <script> var contentFinal; function hueLight(lightID, callback) { $.ajax({ type: 'GET', url: "https://jsonplaceholder.typicode.com/posts/1", dataType: 'json', success:function(data) { if(callback) { contentFinal = callback(data.body); alert(contentFinal); } } }); } var content = "First line "; var finalContent = hueLight("1",function(lightoutput){ return content += lightoutput + " last line"; }); </script> </head> <body> </body> </html> 

Manau, jūs supratote atgalinio ryšio funkcijos sąvoką. Jei kuriate atgalinį ryšį, tai reiškia, kad jūsų sekantis instrukcijų rinkinys priklauso nuo jūsų pavyzdyje nurodyto AJAX skambučio rezultato. Taigi pareiškimas, kuris priklauso nuo AJAX atsakymo, turi būti pats atgalinio ryšio apibrėžimas.

Kitas metodas, kurį galite naudoti, yra uždarymo ir atgalinio ryšio metodo sukūrimas.

-5
16 марта '18 в 15:24 2018-03-16 15:24 atsakymas suteikiamas Nishant'ui kovo 16, 18 d. 15:24 2018-03-16 15:24

Norėdami tvarkyti visus ajax pažadus, setTimeout patikrina pažadą javascript. $. JQuery neigė. Štai kaip galite atsakyti į atsakymą.

 function foo() { var result = $.ajax({ url: '...', // This success callback is not required. You can remove it. // Since we are getting at (1) success: function (response) { // result = response; } }); return result; } // Since this is a Promise object called $Deferred in jQuery // You can attach a then callback which accepts two callback // first one success and second one error foo().then( function( response ) { // This is success callback (1) console.log('success: ', response); }, function( xhr ) { // This is error callback console.log('error: ', xhr); } ) 
-7
13 окт. Atsakymas, kurį pateikė Rajkeshwar Prasad spalio 13 d 2017-10-13 10:12 '17 10:12 2017-10-13 10:12
  • 1
  • 2