


Analisis ringkas tentang perbezaan antara Promise, Generator dan Async
Fungsi Janji dan Async/menunggu kedua-duanya digunakan untuk menyelesaikan masalah tak segerak dalam JavaScript, jadi apakah perbezaan antara keduanya? Artikel berikut akan memperkenalkan kepada anda perbezaan antara Promise, Generator dan Async Saya harap ia akan membantu anda!
Kami tahu bahawa fungsi Promise
dan Async/await
digunakan untuk menyelesaikan masalah tak segerak dalam JavaScript Daripada fungsi panggil balik awal untuk mengendalikan pemprosesan tak segerak, kepada Promise
Daripada mengendalikan pemprosesan tak segerak kepada Generator
memproses pemprosesan tak segerak, dan kemudian kepada Async/await
memproses pemprosesan tak segerak, setiap kemas kini teknikal menjadikan JavaScript mengendalikan pemprosesan tak segerak dengan lebih elegan Dari sudut pandangan semasa, Async/await
dianggap sebagai penyelesaian muktamad untuk pemprosesan tak segerak , menjadikan pemprosesan tak segerak JS semakin seperti tugas segerak. Keadaan tertinggi pengaturcaraan tak segerak ialah anda tidak perlu risau sama ada ia tidak segerak sama sekali.
Sejarah pembangunan penyelesaian tak segerak
1 Fungsi panggil balik
Daripada kod Javascript awal, dalam ES6 Sebelumnya. lahir, pada asasnya semua pemprosesan tak segerak dilaksanakan berdasarkan fungsi panggil balik Anda mungkin pernah melihat kod berikut:
ajax('aaa', () => { // callback 函数体 ajax('bbb', () => { // callback 函数体 ajax('ccc', () => { // callback 函数体 }) }) })
Ya, sebelum kemunculan ES6, kod jenis ini boleh dikatakan Ditemui di mana-mana. Walaupun ia menyelesaikan masalah pelaksanaan tak segerak, ia diikuti dengan masalah Neraka Panggilan Balik yang sering kita dengar:
- Tiada perintah langsung: pelaksanaan fungsi bersarang dengan It is sukar untuk nyahpepijat, yang tidak kondusif untuk penyelenggaraan dan pembacaan
- Gandingan terlalu kuat: apabila tahap bersarang tertentu ditukar, ia akan menjejaskan pelaksanaan keseluruhan panggilan balik
Oleh itu, untuk menyelesaikan masalah ini, masyarakat terlebih dahulu mencadangkan dan melaksanakan Promise
, dan ES6 menulisnya ke dalam standard bahasa untuk menyatukan penggunaannya.
2. Janji
Promise ialah penyelesaian kepada pengaturcaraan tak segerak, yang lebih baik daripada penyelesaian tradisional - fungsi panggil balik dan Acara - lebih munasabah dan berkuasa. Ia dilahirkan untuk menyelesaikan masalah yang disebabkan oleh fungsi panggil balik.
Dengan objek Promise
, operasi tak segerak boleh dinyatakan sebagai proses operasi segerak, mengelakkan lapisan fungsi panggil balik bersarang. Selain itu, objek Promise
menyediakan antara muka bersatu, menjadikannya lebih mudah untuk mengawal operasi tak segerak.
Jadi kita boleh menukar fungsi panggil balik di atas kepada ini: (dengan syarat ajax telah dibalut dengan Janji)
ajax('aaa').then(res=>{ return ajax('bbb') }).then(res=>{ return ajax('ccc') })
Dengan menggunakan Promise
untuk mengendalikan tak segerak, ia lebih baik daripada sebelumnya Fungsi panggil balik kelihatan lebih jelas, menyelesaikan masalah panggilan balik neraka Promise
dan then
lebih boleh diterima dan selaras dengan idea penyegerakan kami.
Tetapi Promise juga mempunyai kekurangannya:
- Ralat dalaman Promise tidak boleh ditangkap menggunakan
try catch
, dan anda hanya boleh menggunakan yang kedua daripadathen
Panggilan balik ataucatch
untuk menangkap
let pro try{ pro = new Promise((resolve,reject) => { throw Error('err....') }) }catch(err){ console.log('catch',err) // 不会打印 } pro.catch(err=>{ console.log('promise',err) // 会打印 })
- Janji akan dilaksanakan serta-merta sebaik sahaja ia dibuat dan tidak boleh dibatalkan
Saya menulis artikel sebelum dan menerangkannya Cara menggunakan Janji dan prinsip pelaksanaan dalamannya. Pelajar yang tidak memahami Promise dengan baik boleh melihat~
Daripada cara menggunakan kepada cara melaksanakan Janji
https://juejin.cn/post/7051364317119119396
3.Fungsi Penjana
Generator
ialah penyelesaian pengaturcaraan tak segerak yang disediakan oleh ES6, dan tingkah laku sintaksisnya berbeza sama sekali daripada fungsi tradisional. Generator
Fungsi membawa pengaturcaraan tak segerak JavaScript ke tahap yang baharu.
Pengisytiharan
adalah serupa dengan pengisytiharan fungsi, kecuali terdapat asterisk antara kata kunci function
dan nama fungsi, dan fungsi yield
ungkapan digunakan di dalam badan untuk mentakrifkan keadaan dalaman yang berbeza (yield
bermaksud "output" dalam bahasa Inggeris).
function* gen(x){ const y = yield x + 6; return y; } // yield 如果用在另外一个表达式中,要放在()里面 // 像上面如果是在=右边就不用加() function* genOne(x){ const y = `这是第一个 yield 执行:${yield x + 1}`; return y; }
Pelaksanaan
const g = gen(1); //执行 Generator 会返回一个Object,而不是像普通函数返回return 后面的值 g.next() // { value: 7, done: false } //调用指针的 next 方法,会从函数的头部或上一次停下来的地方开始执行,直到遇到下一个 yield 表达式或return语句暂停,也就是执行yield 这一行 // 执行完成会返回一个 Object, // value 就是执行 yield 后面的值,done 表示函数是否执行完毕 g.next() // { value: undefined, done: true } // 因为最后一行 return y 被执行完成,所以done 为 true
Selepas memanggil fungsi Penjana, fungsi itu tidak dilaksanakan, dan apa yang dikembalikan bukanlah hasil operasi fungsi Ia adalah objek penunjuk yang menunjuk kepada keadaan dalaman, iaitu 遍历器对象(Iterator Object)
. Seterusnya, kaedah next
objek traverser mesti dipanggil untuk mengalihkan penunjuk ke keadaan seterusnya.
Jadi fungsi panggil balik di atas boleh ditulis seperti ini:
function *fetch() { yield ajax('aaa') yield ajax('bbb') yield ajax('ccc') } let gen = fetch() let res1 = gen.next() // { value: 'aaa', done: false } let res2 = gen.next() // { value: 'bbb', done: false } let res3 = gen.next() // { value: 'ccc', done: false } let res4 = gen.next() // { value: undefined, done: true } done为true表示执行结束
Oleh kerana objek traverser dikembalikan oleh fungsi Generator, keadaan dalaman seterusnya akan dilalui hanya dengan memanggil next
kaedah, jadi sebenarnya Menyediakan fungsi yang boleh menjeda pelaksanaan. yield
Ekspresi ialah bendera jeda. Logik operasi
kaedah next
objek penyeberang adalah seperti berikut.
(1) Apabila menemui ungkapan yield
, pelaksanaan operasi seterusnya akan digantung dan nilai ungkapan serta-merta mengikuti yield
akan digunakan sebagai nilai atribut value
yang dikembalikan objek .
(2) Kali seterusnya kaedah next
dipanggil, pelaksanaan diteruskan sehingga ungkapan yield
seterusnya ditemui.
(3)如果没有再遇到新的yield
表达式,就一直运行到函数结束,直到return
语句为止,并将return
语句后面的表达式的值,作为返回的对象的value
属性值。
(4)如果该函数没有return
语句,则返回的对象的value
属性值为undefined
。
yield
表达式本身没有返回值,或者说总是返回undefined
。next
方法可以带一个参数,该参数就会被当作上一个yield
表达式的返回值。
怎么理解这句话?我们来看下面这个例子:
function* foo(x) { var y = 2 * (yield (x + 1)); var z = yield (y / 3); return (x + y + z); } var a = foo(5); a.next() // Object{value:6, done:false} a.next() // Object{value:NaN, done:false} a.next() // Object{value:NaN, done:true} var b = foo(5); b.next() // { value:6, done:false } b.next(12) // { value:8, done:false } b.next(13) // { value:42, done:true }
由于yield
没有返回值,所以(yield(x+1))执行后的值是undefined
,所以在第二次执行a.next()
是其实是执行的2*undefined
,所以值是NaN
,所以下面b的例子中,第二次执行b.next()
时传入了12,它会当成第一次b.next()
的执行返回值,所以b的例子中能够正确计算。这里不能把next执行结果中的value值与yield返回值搞混了,它两不是一个东西
yield与return的区别
相同点:
- 都能返回语句后面的那个表达式的值
- 都可以暂停函数执行
区别:
- 一个函数可以有多个 yield,但是只能有一个 return
- yield 有位置记忆功能,return 没有
4.Async/await
Async/await
其实就是上面Generator
的语法糖,async
函数其实就相当于funciton *
的作用,而await
就相当与yield
的作用。而在async/await
机制中,自动包含了我们上述封装出来的spawn
自动执行函数。
所以上面的回调函数又可以写的更加简洁了:
async function fetch() { await ajax('aaa') await ajax('bbb') await ajax('ccc') } // 但这是在这三个请求有相互依赖的前提下可以这么写,不然会产生性能问题,因为你每一个请求都需要等待上一次请求完成后再发起请求,如果没有相互依赖的情况下,建议让它们同时发起请求,这里可以使用Promise.all()来处理
async
函数对Generator
函数的改进,体现在以下四点:
- 内置执行器:
async
函数执行与普通函数一样,不像Generator
函数,需要调用next
方法,或使用co
模块才能真正执行 - 语意化更清晰:
async
和await
,比起星号和yield
,语义更清楚了。async
表示函数里有异步操作,await
表示紧跟在后面的表达式需要等待结果。 - 适用性更广:
co
模块约定,yield
命令后面只能是 Thunk 函数或 Promise 对象,而async
函数的await
命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)。 - 返回值是Promise:
async
函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then
方法指定下一步的操作。
async函数
async函数的返回值为Promise对象,所以它可以调用then方法
async function fn() { return 'async' } fn().then(res => { console.log(res) // 'async' })
await表达式
await 右侧的表达式一般为 promise 对象, 但也可以是其它的值
如果表达式是 promise 对象, await 返回的是 promise 成功的值
如果表达式是其它值, 直接将此值作为 await 的返回值
await后面是Promise对象会阻塞后面的代码,Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果
所以这就是await必须用在async的原因,async刚好返回一个Promise对象,可以异步执行阻塞
function fn() { return new Promise((resolve, reject) => { setTimeout(() => { resolve(1000) }, 1000); }) } function fn1() { return 'nanjiu' } async function fn2() { // const value = await fn() // await 右侧表达式为Promise,得到的结果就是Promise成功的value // const value = await '南玖' const value = await fn1() console.log('value', value) } fn2() // value 'nanjiu'
异步方案比较
后三种方案都是为解决传统的回调函数而提出的,所以它们相对于回调函数的优势不言而喻。而async/await
又是Generator
函数的语法糖。
- Promise的内部错误使用
try catch
捕获不到,只能只用then
的第二个回调或catch
来捕获,而async/await
的错误可以用try catch
捕获 Promise
一旦新建就会立即执行,不会阻塞后面的代码,而async
函数中await后面是Promise对象会阻塞后面的代码。async
函数会隐式地返回一个promise
,该promise
的reosolve
值就是函数return的值。- 使用
async
函数可以让代码更加简洁,不需要像Promise
一样需要调用then
方法来获取返回值,不需要写匿名函数处理Promise
的resolve值,也不需要定义多余的data变量,还避免了嵌套代码。
说了这么多,顺便看个题吧~
console.log('script start') async function async1() { await async2() console.log('async1 end') } async function async2() { console.log('async2 end') } async1() setTimeout(function() { console.log('setTimeout') }, 0) new Promise(resolve => { console.log('Promise') resolve() }) .then(function() { console.log('promise1') }) .then(function() { console.log('promise2') }) console.log('script end')
解析:
打印顺序应该是: script start -> async2 end -> Promise -> script end -> async1 end -> promise1 -> promise2 -> setTimeout
老规矩,全局代码自上而下执行,先打印出script start
,然后执行async1(),里面先遇到await async2(),执行async2,打印出async2 end
,然后await后面的代码放入微任务队列,接着往下执行new Promise,打印出Promise
,遇见了resolve,将第一个then方法放入微任务队列,接着往下执行打印出script end
,全局代码执行完了,然后从微任务队列中取出第一个微任务执行,打印出async1 end
,再取出第二个微任务执行,打印出promise1
,然后这个then方法执行完了,当前Promise的状态为fulfilled
,它也可以出发then的回调,所以第二个then这时候又被加进了微任务队列,然后再出微任务队列中取出这个微任务执行,打印出promise2
,此时微任务队列为空,接着执行宏任务队列,打印出setTimeout
。
解题技巧:
- 无论是then还是catch里的回调内容只要代码正常执行或者正常返回,则当前新的Promise实例为fulfilled状态。如果有报错或返回Promise.reject()则新的Promise实例为rejected状态。
- fulfilled状态能够触发then回调
- rejected状态能够触发catch回调
- 执行async函数,返回的是Promise对象
- await相当于Promise的then并且同一作用域下await下面的内容全部作为then中回调的内容
- 异步中先执行微任务,再执行宏任务
【相关推荐:javascript学习教程】
Atas ialah kandungan terperinci Analisis ringkas tentang perbezaan antara Promise, Generator dan Async. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian Pengenalan: Dengan perkembangan teknologi yang berterusan, teknologi pengecaman pertuturan telah menjadi bahagian penting dalam bidang kecerdasan buatan. Sistem pengecaman pertuturan dalam talian berdasarkan WebSocket dan JavaScript mempunyai ciri kependaman rendah, masa nyata dan platform merentas, dan telah menjadi penyelesaian yang digunakan secara meluas. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian.

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

Pengenalan kepada cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata: Dengan populariti Internet dan kemajuan teknologi, semakin banyak restoran telah mula menyediakan perkhidmatan pesanan dalam talian. Untuk melaksanakan sistem pesanan dalam talian masa nyata, kami boleh menggunakan teknologi JavaScript dan WebSocket. WebSocket ialah protokol komunikasi dupleks penuh berdasarkan protokol TCP, yang boleh merealisasikan komunikasi dua hala masa nyata antara pelanggan dan pelayan. Dalam sistem pesanan dalam talian masa nyata, apabila pengguna memilih hidangan dan membuat pesanan

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian Dalam era digital hari ini, semakin banyak perniagaan dan perkhidmatan perlu menyediakan fungsi tempahan dalam talian. Adalah penting untuk melaksanakan sistem tempahan dalam talian yang cekap dan masa nyata. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian dan memberikan contoh kod khusus. 1. Apakah itu WebSocket? WebSocket ialah kaedah dupleks penuh pada sambungan TCP tunggal.

Dalam kehidupan seharian, kita sering menghadapi masalah antara janji dan menunaikan. Sama ada dalam hubungan peribadi atau transaksi perniagaan, menunaikan janji adalah kunci untuk membina kepercayaan. Walau bagaimanapun, kebaikan dan keburukan komitmen sering menjadi kontroversi. Artikel ini akan meneroka kebaikan dan keburukan komitmen dan memberi beberapa nasihat tentang cara untuk mengekalkan kata-kata anda. Faedah yang dijanjikan adalah jelas. Pertama, komitmen membina kepercayaan. Apabila seseorang menepati kata-katanya, dia membuat orang lain percaya bahawa dia seorang yang boleh dipercayai. Kepercayaan adalah ikatan yang terjalin antara orang, yang boleh menjadikan orang lebih banyak

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

Penjelasan terperinci Promise.resolve() memerlukan contoh kod khusus Promise ialah mekanisme dalam JavaScript untuk mengendalikan operasi tak segerak. Dalam pembangunan sebenar, selalunya perlu untuk memproses beberapa tugas tak segerak yang perlu dilaksanakan mengikut turutan, dan kaedah Promise.resolve() digunakan untuk mengembalikan objek Promise yang telah dipenuhi. Promise.resolve() ialah kaedah statik kelas Promise, yang menerima a
