Apa perbedaan antara:
new Promise(function(res, rej) {
res("aaa");
})
.then(function(result) {
return "bbb";
})
.then(function(result) {
console.log(result);
});
dan ini:
new Promise(function(res, rej) {
res("aaa");
})
.then(function(result) {
return Promise.resolve("bbb");
})
.then(function(result) {
console.log(result);
});
Saya bertanya karena saya mendapatkan perilaku yang berbeda Menggunakan layanan Angular dan $ http dengan chaining .then (). Sedikit kode terlalu banyak maka pertama contoh di atas.
javascript
angularjs
promise
q
spirytus
sumber
sumber
Promise.resolve()
contoh kedua tidak perlu.then
pawang, pada kenyataannya, itu adalah aspek kunci dari spesifikasi janji yang dapat Anda lakukan.then
- istilah 'bahasa lain' untuk ini adalahthen
amap
dan aflatMap
.new Promise((res, rej) => { return fetch('//google.com').then(() => { return "haha"; }) }).then((result) => alert(result));
Kode ini hanya akan hang (tidak diselesaikan selamanya). Tapi jika saya mengubahreturn "haha";
kereturn res("haha");
kemudian itu akan bekerja dan waspada "haha". Bukankah fetch (). Then () sudah membungkus "haha" menjadi janji terselesaikan?Jawaban:
Aturannya adalah, jika fungsi yang ada di
then
handler mengembalikan nilai, janji itu diselesaikan / ditolak dengan nilai itu, dan jika fungsi mengembalikan janji, apa yang terjadi adalah,then
klausa berikutnya adalahthen
klausa janji yang dikembalikan fungsi , jadi, dalam hal ini, contoh pertama jatuh melalui urutan normalthens
dan mencetak nilai - nilai seperti yang diharapkan, dalam contoh kedua, objek janji yang dikembalikan ketika Anda melakukannyaPromise.resolve("bbb")
adalahthen
yang dipanggil saat rantai (untuk semua maksud dan tujuan). Cara kerjanya sebenarnya dijelaskan di bawah ini secara lebih rinci.Mengutip dari Janji / spec A +:
Hal utama yang perlu diperhatikan di sini adalah baris ini:
sumber
then
pawang mengembalikan janji. +1 untuk referensi spesifikasi.[[Resolve]]
disebut baik padathen
able dan nilai sehingga pada dasarnya itu membungkus nilai dengan janji sehinggareturn "aaa"
sama denganreturn Promise.resolve("aaa")
danreturn Promise.resolve("aaa")
sama denganreturn Promise.resolve(Promise.resolve("aaa"))
- karena tekad adalah idempoten menyebutnya dengan nilai lebih daripada sekali memiliki hasil yang sama."aaa"
danreturn Promise.resolve("aaa")
dapat dipertukarkan dalamthen
hal apapun?Secara sederhana, di dalam
then
fungsi handler:A) Kapan
x
suatu nilai (angka, string, dll):return x
setara denganreturn Promise.resolve(x)
throw x
setara denganreturn Promise.reject(x)
B) Kapan
x
Janji yang sudah diselesaikan (tidak tertunda lagi):return x
setara denganreturn Promise.resolve(x)
, jika Janji sudah terselesaikan.return x
setara denganreturn Promise.reject(x)
, jika Janji sudah ditolak.C) Kapan
x
Janji yang tertunda:return x
akan mengembalikan Janji yang tertunda, dan akan dievaluasi selanjutnyathen
.Baca lebih lanjut tentang topik ini di dokumen Promise.prototype.then () .
sumber
Kedua contoh Anda harus berperilaku sama.
Nilai yang dikembalikan ke dalam
then()
handler menjadi nilai resolusi dari janji yang dikembalikan dari ituthen()
. Jika nilai yang dikembalikan ke dalam.then
adalah janji, janji yang dikembalikan olehthen()
akan "mengadopsi keadaan" dari janji itu dan menyelesaikan / menolak seperti halnya janji yang dikembalikan.Dalam contoh pertama Anda, Anda kembali
"bbb"
kethen()
penangan pertama , sehingga"bbb"
diteruskan kethen()
penangan berikutnya .Dalam contoh kedua, Anda mengembalikan janji yang segera diselesaikan dengan nilai
"bbb"
, sehingga"bbb"
diteruskan kethen()
penangan berikutnya . (DiPromise.resolve()
sini luar).Hasilnya sama.
Jika Anda dapat menunjukkan kepada kami contoh yang benar-benar menunjukkan perilaku yang berbeda, kami dapat memberi tahu Anda mengapa itu terjadi.
sumber
Promise.resolve();
vsreturn;
?undefined
alih - alih"bbb"
.Anda sudah mendapat jawaban formal yang bagus. Saya pikir saya harus menambahkan yang pendek.
Hal-hal berikut identik dengan Janji / Janji + :
Promise.resolve
(Dalam kasus Sudut Anda itu$q.when
)new $q
.then
panggilan balik.Jadi yang berikut semuanya identik untuk janji atau nilai X:
Dan tidak mengherankan, spesifikasi janji didasarkan pada Prosedur Resolusi Janji yang memungkinkan interoperasi yang mudah antara perpustakaan (seperti $ q dan janji asli) dan membuat hidup Anda secara keseluruhan lebih mudah. Setiap kali sebuah janji resolusi mungkin terjadi, sebuah resolusi muncul menciptakan keseluruhan konsistensi.
sumber
Promise.resolve().then(function(){ return x; });
? Saya menemukan potongan melakukan sesuatu yang serupa (itu disebut fungsi di dalamthen
blok). Saya pikir itu kurang lebih seperti melakukan timeout, tetapi sedikit lebih cepat. jsben.ch/HIfDowith
blok di atas objek atau proxy dengan pengaksesx
properti yang melempar pengecualian. Dalam hal itu Promise.resolve (x) akan menyebabkan kesalahan yang dilemparkan tetapiPromise.resolve().then(function(){ return x; });
akan menjadi janji yang ditolak karena kesalahan dilemparkan dalam athen
).if (validator) { Promise.resolve().then(() => { this._cdRef.markForCheck(); }); }
. Di sini janji tidak diberikan, jadi apa gunanya? Waktu habis akan memiliki (kurang lebih) efek yang sama, atau tidak?Satu-satunya perbedaan adalah bahwa Anda menciptakan janji yang tidak perlu ketika Anda melakukannya
return Promise.resolve("bbb")
. Mengembalikan janji darionFulfilled()
pawang dimulai dengan resolusi janji . Begitulah cara kerja chaining janji .sumber