Saya memiliki fungsi foo yang membuat permintaan AJAX. Bagaimana saya bisa mengembalikan respons dari foo?

Saya mencoba mengembalikan nilai dari panggilan balik success serta menetapkan respons terhadap variabel lokal di dalam fungsi dan mengembalikan yang itu, tetapi tidak satu pun dari cara itu mengembalikan respons.

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`.
5787
Felix Kling 8 जिंदा 2013, 21:06

11 जवाब

Menggunakan ES2017 Anda harus memiliki ini sebagai deklarasi fungsi

async function foo() {
    var response = await $.ajax({url: '...'})
    return response;
}

Dan mengeksekusi seperti ini.

(async function() {
    try {
        var result = await foo()
        console.log(result)
    } catch (e) {}
})()

Atau sintaksis janji

foo().then(response => {
    console.log(response)

}).catch(error => {
    console.log(error)

})
16
Fernando Carvajal 24 जिंदा 2018, 06:18

Jawaban singkat adalah, Anda harus menerapkan panggilan balik seperti ini:

function callback(response) {
    // Here you can do what ever you want with the response object.
    console.log(response);
}

$.ajax({
    url: "...",
    success: callback
});
85
Pablo Matias Gomez 9 अगस्त 2016, 18:32

Anda menggunakan AJAX secara tidak benar. Idenya bukan untuk mengembalikan apa pun, tetapi sebaliknya menyerahkan data ke sesuatu yang disebut fungsi panggilan balik, yang menangani data.

अर्थात्:

function handleData( responseData ) {

    // Do what you want with the data
    console.log(responseData);
}

$.ajax({
    url: "hi.php",
    ...
    success: function ( data, status, XHR ) {
        handleData(data);
    }
});

Mengembalikan apa pun di handler kirim tidak akan melakukan apa-apa. Anda juga harus meninggalkan data, atau melakukan apa yang Anda inginkan langsung di dalam fungsi kesuksesan.

256
Peter Mortensen 21 नवम्बर 2015, 14:07

Solusi paling sederhana adalah membuat fungsi JavaScript dan menyebutnya untuk panggilan balik ajax success.

function callServerAsync(){
    $.ajax({
        url: '...',
        success: function(response) {

            successCallback(response);
        }
    });
}

function successCallback(responseObj){
    // Do something like read the response and show data
    alert(JSON.stringify(responseObj)); // Only applicable to JSON response
}

function foo(callback) {

    $.ajax({
        url: '...',
        success: function(response) {
           return callback(null, response);
        }
    });
}

var result = foo(function(err, result){
          if (!err)
           console.log(result);    
}); 
243
clearlight 15 जिंदा 2017, 06:17

Saya akan menjawab dengan komik yang tampak mengerikan dan hand-draw. Gambar kedua adalah alasan mengapa result adalah undefined dalam contoh kode Anda.

enter image description here

233
Johannes Fahrenkrug 11 अगस्त 2016, 17:12

Lihat contoh ini:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope,$http) {

    var getJoke = function(){
        return $http.get('http://api.icndb.com/jokes/random').then(function(res){
            return res.data.value;  
        });
    }

    getJoke().then(function(res) {
        console.log(res.joke);
    });
});

Seperti yang Anda lihat getJoke adalah mengembalikan diselesaikan janji (diselesaikan saat mengembalikan res.data.value). Jadi Anda tunggu sampai $ http.get Permintaan selesai dan kemudian console.log (res.joke) dijalankan (sebagai aliran asinkron normal).

Ini adalah PLNKR:

Http: // embed. Tamu wanita cantik. CO / XL NR7HP CAI HJ seperti KM JF SG /

ES6 Way (Async - menunggu)

(function(){
  async function getJoke(){
    let response = await fetch('http://api.icndb.com/jokes/random');
    let data = await response.json();
    return data.value;
  }

  getJoke().then((joke) => {
    console.log(joke);
  });
})();
113
Francisco Carmona 23 नवम्बर 2018, 12:19

Ini adalah salah satu tempat yang dua cara mengikat data atau toko konsep yang digunakan dalam banyak kerangka kerja javascript baru akan bekerja dengan baik untuk Anda ...

Jadi, jika Anda menggunakan angular, bereaksi atau kerangka kerja lain yang dua cara mengikat data atau toko konsep Masalah ini cukup untuk Anda, Jadi dalam kata yang mudah, hasil Anda adalah undefined pada tahap pertama, jadi Anda punya result = undefined sebelum Anda menerima data, maka segera setelah Anda mendapatkan hasilnya, itu akan diperbarui dan ditugaskan untuk Nilai baru yang tanggapan dari panggilan Ajax Anda ...

Tetapi bagaimana Anda dapat melakukannya dengan murni javascript atau jQuery Misalnya seperti yang Anda ajukan dalam pertanyaan ini?

Anda dapat menggunakan panggilan balik , janji dan baru-baru ini diamati untuk menanganinya untuk Anda, misalnya dalam janji kami memiliki beberapa fungsi seperti {{x0} } atau then() yang akan dijalankan ketika data Anda siap untuk Anda, sama dengan panggilan balik atau berlangganan Fungsi pada diamati .

Misalnya dalam kasus Anda yang Anda gunakan jQuery , Anda dapat melakukan sesuatu seperti ini:

$(document).ready(function(){
    function foo() {
        $.ajax({url: "api/data", success: function(data){
            fooDone(data); //after we have data, we pass it to fooDone
        }});
    };

    function fooDone(data) {
        console.log(data); //fooDone has the data and console.log it
    };

    foo(); //call happens here
});

Untuk informasi lebih lanjut tentang studi tentang janji dan diamati yang merupakan cara baru untuk melakukan hal-hal asinc ini.

112
Alireza 23 सितंबर 2019, 03:14

Pendekatan lain untuk mengembalikan nilai dari fungsi asinkron, adalah untuk melewati objek yang akan menyimpan hasil dari fungsi asinkron.

Berikut ini adalah contoh yang sama:

var async = require("async");

// This wires up result back to the caller
var result = {};
var asyncTasks = [];
asyncTasks.push(function(_callback){
    // some asynchronous operation
    $.ajax({
        url: '...',
        success: function(response) {
            result.response = response;
            _callback();
        }
    });
});

async.parallel(asyncTasks, function(){
    // result is available after performing asynchronous operation
    console.log(result)
    console.log('Done');
});

Saya menggunakan objek result untuk menyimpan nilai selama operasi asinkron. Ini memungkinkan hasilnya tersedia bahkan setelah pekerjaan asinkron.

Saya sering menggunakan pendekatan ini. Saya akan tertarik untuk mengetahui seberapa baik pendekatan ini bekerja di mana kabel hasil kembali melalui modul berturut-turut terlibat.

101
Peter Mortensen 17 पद 2016, 12:55

Ecmascript 6 memiliki 'generator' yang memungkinkan Anda untuk dengan mudah memprogram dengan gaya asinkron.

function* myGenerator() {
    const callback = yield;
    let [response] = yield $.ajax("https://stackoverflow.com", {complete: callback});
    console.log("response is:", response);

    // examples of other things you can do
    yield setTimeout(callback, 1000);
    console.log("it delayed for 1000ms");
    while (response.statusText === "error") {
        [response] = yield* anotherGenerator();
    }
}

Untuk menjalankan kode di atas, Anda melakukan ini:

const gen = myGenerator(); // Create generator
gen.next(); // Start it
gen.next((...args) => gen.next([...args])); // Set its callback function

Jika Anda perlu menargetkan browser yang tidak mendukung ES6, Anda dapat menjalankan kode melalui Babel atau Closure-Compiler untuk menghasilkan ECMAScript 5.

Callback ...args dibungkus dalam array dan dirusak ketika Anda membacanya sehingga pola dapat mengatasi panggilan balik yang memiliki banyak argumen. Misalnya dengan Node FS:

const [err, data] = yield fs.readFile(filePath, "utf-8", callback);
42
James 31 जुलाई 2018, 10:35

Gunakan fungsi callback() di dalam kesuksesan foo(). Coba dengan cara ini. Sederhana dan mudah dimengerti.

var lat = "";
var lon = "";
function callback(data) {
    lat = data.lat;
    lon = data.lon;
}
function getLoc() {
    var url = "http://ip-api.com/json"
    $.getJSON(url, function(data) {
        callback(data);
    });
}

getLoc();
37
Alex Weitz 17 नवम्बर 2017, 09:15

Tentu saja ada banyak pendekatan seperti permintaan sinkron, janji, tetapi dari pengalaman saya, saya pikir Anda harus menggunakan pendekatan panggilan balik. Ini wajar dengan perilaku asinkron JavaScript. Jadi, cuplikan kode Anda dapat ditulis ulang sedikit berbeda:

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            myCallback(response);
        }
    });

    return result;
}

function myCallback(response) {
    // Does something.
}
28
Michał Perłakowski 7 मार्च 2018, 14:23