Kembali dari janji lalu ()

119

Saya punya kode javascript seperti ini:

function justTesting() {
  promise.then(function(output) {
    return output + 1;
  });
}

var test = justTesting();

Saya selalu mendapatkan nilai yang tidak ditentukan untuk tes var. Saya pikir itu karena janji belum terselesaikan..ada cara untuk mengembalikan nilai dari sebuah janji?

Priscy
sumber
21
nilai kembali dari then()panggilan sekali lagi adalah janji, yang membungkus nilai yang Anda kembalikan.
Sirko
Anda memiliki kesalahan sintaks, saya rasa ini bahkan tidak mem-parsing.
djechlin
4
test tidak ditentukan karena justTesting tidak mengembalikan apa pun dalam contoh Anda (Anda tidak memiliki hasil). Tambahkan pengembalian dan tes akan didefinisikan sebagai janji.
Jerome WAGNER
1
Terima kasih atas umpan baliknya .. intinya adalah menetapkan keluaran +1 untuk diuji.
Priscy
4
Apa variabelnya promise. Anda tidak menunjukkannya di mana pun dan Anda tidak mengembalikan apa pun dari justTesting()fungsi Anda . Jika Anda menginginkan bantuan yang lebih baik, Anda perlu menjelaskan masalah apa yang Anda coba selesaikan daripada hanya menunjukkan kepada kami kode yang sangat "tidak aktif" sehingga tidak menggambarkan apa yang sebenarnya Anda coba lakukan. Jelaskan masalah yang Anda coba selesaikan.
jfriend00

Jawaban:

136

Ketika Anda mengembalikan sesuatu dari then()panggilan balik, itu sedikit ajaib. Jika Anda mengembalikan nilai, nilai berikutnya then()dipanggil dengan nilai itu. Namun, jika Anda mengembalikan sesuatu seperti promise, yang berikutnya akan then()menunggu, dan hanya dipanggil saat promise itu selesai (berhasil / gagal).

Sumber: https://developers.google.com/web/fundamentals/getting-started/primers/promises#queuing-asynchronous-actions

c0ming
sumber
Sepertinya karena alasan ini, maka saya dapat melakukan rantai janji untuk iterasi array dengan permintaan Ajax secara sinkron di stackoverflow.com/q/53651266/2028440
Bằng Rikimaru
84
Tidak menjawab pertanyaan itu.
Andrew
Tautan
Marinos An
1
Jadi apa solusinya?
Apurva
58

Untuk menggunakan janji, Anda harus memanggil fungsi yang membuat janji atau Anda harus membuatnya sendiri. Anda tidak benar-benar menjelaskan masalah apa yang sebenarnya Anda coba selesaikan, tetapi inilah cara Anda membuat janji sendiri:

function justTesting(input) {
    return new Promise(function(resolve, reject) {
        // some async operation here
        setTimeout(function() {
            // resolve the promise with some value
            resolve(input + 10);
        }, 500);
    });
}

justTesting(29).then(function(val) {
   // you access the value from the promise here
   log(val);
});

// display output in snippet
function log(x) {
    document.write(x);
}

Atau, jika Anda sudah memiliki fungsi yang mengembalikan sebuah janji, Anda bisa menggunakan fungsi itu dan mengembalikan janji:

// function that returns a promise
function delay(t) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve();
    }, t);
  });
}

function justTesting(input) {
  return delay(100).then(function() {
    return input + 10;
  });
}

justTesting(29).then(function(val) {
  // you access the value from the promise here
  log(val);
});

// display output in snippet
function log(x) {
  document.write(x);
}

jfriend00
sumber
2
apa yang membuat saya marah adalah ganda return, yaitu justTestingkata return.then => return. Saya tahu ini berfungsi karena saya telah menerapkan ini (bcs linting memaksa saya untuk, menjauh dari new Promise), tetapi dapatkah Anda menjelaskan cara memahami / memikirkan pasangan pengembalian / pengembalian itu?
Ronnie Royston
2
@RonRoyston - Pertama, fungsi yang Anda berikan .then()adalah fungsi terpisah dari fungsi yang memuatnya sehingga ketika dipanggil, ia memiliki nilai kembaliannya sendiri. Kedua, nilai pengembalian dari .then()penangan menjadi nilai janji yang terselesaikan. Jadi, .then(val => {return 2*val;})mengubah nilai yang diselesaikan dari valmenjadi 2*val.
jfriend00
13

Apa yang telah saya lakukan di sini adalah bahwa saya telah mengembalikan sebuah janji dari fungsi justTesting. Anda kemudian bisa mendapatkan hasilnya saat fungsi diselesaikan.

// new answer

function justTesting() {
  return new Promise((resolve, reject) => {
    if (true) {
      return resolve("testing");
    } else {
      return reject("promise failed");
   }
 });
}

justTesting()
  .then(res => {
     let test = res;
     // do something with the output :)
  })
  .catch(err => {
    console.log(err);
  });

Semoga ini membantu!

// old answer

function justTesting() {
  return promise.then(function(output) {
    return output + 1;
  });
}

justTesting().then((res) => {
     var test = res;
    // do something with the output :)
    }
Vidur Singla
sumber
Apa yang akan terjadi jika dalam "// melakukan sesuatu dengan output" saya meletakkan pernyataan return? Misalnya: Saya akan memiliki "JustTesting (). Then ..." dalam fungsi induk. Apakah saya dapat mengembalikan nilai dalam bagian "lalu"?
mrzepka
Jika Anda ingin mengembalikan nilai dari // lakukan sesuatu dengan hasilnya, Anda harus menambahkan pengembalian sebelum justTesing (). Contoh, "return justTesting (). Then ((res) => {return res;});
Vidur Singla
Baiklah itu yang saya harapkan, saya hanya ingin memastikan :) Terima kasih!
mrzepka
bagaimana jika kita mengembalikan tes dari saat itu?
MeVimalkumar
3

Saya lebih suka menggunakan perintah "await" dan fungsi async untuk menghilangkan kerancuan janji,

Dalam hal ini saya akan menulis fungsi asynchronous pertama, ini akan digunakan sebagai pengganti fungsi anonim yang disebut di bawah bagian "promise.then" dari pertanyaan ini:

async function SubFunction(output){

   // Call to database , returns a promise, like an Ajax call etc :

   const response = await axios.get( GetApiHost() + '/api/some_endpoint')

   // Return :
   return response;

}

dan kemudian saya akan memanggil fungsi ini dari fungsi utama:

async function justTesting() {
   const lv_result = await SubFunction(output);

   return lv_result + 1;
}

Memperhatikan bahwa saya mengembalikan fungsi utama dan sub fungsi ke fungsi asinkron di sini.

beemaster
sumber
Benar ... Menggunakan menunggu membuatnya lebih bersih dan juga memecahkan masalah
karthikeyan