摘要:又有好些天沒有動筆了,這幾天一直在斷斷續(xù)續(xù)的學(xué)習(xí)和,今天終于能夠把著兩個玩意結(jié)合起來了解決異步問題了。今天我先把相關(guān)的用法和對異步的處理分享給大家。老樣子,還是先模擬一個。
又有好些天沒有動筆了,這幾天一直在斷斷續(xù)續(xù)的學(xué)習(xí)Promise和generator,今天終于能夠把著兩個玩意結(jié)合起來了解決異步問題了。今天我先把promise相關(guān)的用法和對異步的處理分享給大家。
老樣子,還是先模擬一個Promise。
//咳咳這樣就實現(xiàn)了嘛 let MyPromise = Promise;
開個玩笑,其實這兩天我也一直在看Promise的實現(xiàn),但是還是沒有怎么理解。所以Promise的代碼實現(xiàn)我暫時先放一放,等我完全理解再來新開一篇分享。這里先給大家推薦幾篇我覺得比較好的Promise實現(xiàn)的博客,想要學(xué)習(xí)的小伙伴可以先到那邊一睹為快,當(dāng)然等我更新了之后大家還是要來給我文章點贊的哈。
徹底理解Promise對象——用es5語法實現(xiàn)一個自己的Promise(上篇)這一篇文章用的es5的語法,對es6不是很熟悉的同學(xué)可以用這篇文章頂一下
Promise實現(xiàn)原理(附源碼)這一篇呢是用到了class的,所以需要大家對es6有所了解,也是一篇好文章
接下來我介紹一下Promise最常用的幾個部分:
首先先介紹最簡單的只有一個Promise對象的用法
//Promise()接收一個函數(shù),并且在創(chuàng)建這個Promise對象的同時,接收的這個函數(shù)就會被立刻執(zhí)行 var promise = new Promise(function (resolve, reject) { //resolve用來接收成功的返回,reject用來接收失敗的返回 setTimeout(function () { //這里我們生成一個隨機數(shù),并在接下來根據(jù)這個隨機數(shù)的大小來判斷這個異步是否成功 let num = Math.random(); if (num > 0.8) { //接收失敗的原因 console.log("reject") reject(num + "大于0.8,這次異步操作失敗了") } else { //接收成功的數(shù)據(jù) console.log("resolve") resolve(num + "小于0.8,這次異步操作成功了") } }, 100) }); console.log("一個Promise對象生成了"); //Promise對象的.then()方法接收兩個回調(diào),第一個為成功回調(diào),第二個為失敗回調(diào) //這兩個回調(diào)會在上面的resolve或者reject函數(shù)生效后被調(diào)用 promise.then(function (data) { //這個函數(shù)會在上面的resolve函數(shù)被調(diào)用后生效,這里的data就是上面resolve()中接收的值 console.log(data) }, function (err) { ///這個函數(shù)會在上面的reject函數(shù)被調(diào)用后生效,這里的err就是上面reject()中接收的值 console.error(err) }); console.log("promise的.then方法被調(diào)用了")
大家可以按F12喚起控制臺,然后把這段代碼運行幾次??纯磿惺裁唇Y(jié)果;
多運行幾次以后,大家應(yīng)該可以看到這兩類結(jié)果:
其中的undefind是console.log("promise的.then方法被調(diào)用了")這行代碼的返回,大家可以不用關(guān)注。在這里可以看到不論是成功的結(jié)果還是失敗的結(jié)果都是在定時器執(zhí)行后再打印出來的。這種寫法可以幫助我們實現(xiàn)簡單的異步編程。
接下介紹多個Promise對象同時使用的用法, 先介紹最常見的.then()鏈?zhǔn)秸{(diào)用的方法
//用來快速生成一個Promise對象,接收一個日志列表,不論成功還是失敗都會往日志列表中添加一條日志 function promise(log) { return new Promise(function (resolve, reject) { setTimeout(function () { log = log || []; //和上次的例子一樣,利用隨機數(shù)來隨機失敗和成功 let num = Math.random(); if (num > 0.5) { log.push(num + "大于0.5,這次異步操作失敗了"); reject(log) } else { log.push(num + "小于0.5,這次異步操作成功了"); resolve(log) } }, 100) }) }
.then()中返回了Promise對象的情況
var promise1 = promise(); //promise1.then()方法會返回一個Promise對象 //如果我們在.then()生效的那個 !!!回調(diào)方法!!! 中有返回一個Promise對象的話,該對象會被 !!!.then()方法!!! 返回 //先看返回了Promise對象的方式 promise1.then(function (data) { console.log(data); return promise(data) }, function (err) { console.error(err); return promise(err) }).then(function (data) { console.log(data) }, function (err) { console.error(err) });
這段代碼運行后一共會有四種結(jié)果:
兩次都成功
兩次都失敗
第一次失敗,第二次成功
第一次成功,第二次失敗
通過這種方法我們可以用比較清晰的方式來書寫我們的異步代碼。特別是多個異步操作嵌套的時候,可以鏈?zhǔn)秸{(diào)用.then()來實現(xiàn),這樣的代碼看起來邏輯更清晰;
剛剛看完了返回了Promise對象的場景,再來看看沒有返回Promise的場景
//如果我們沒有返回Promise對象,.then()就會將我們返回的東西包裝成一個Promise對象(沒有返回就相當(dāng)于返回了undefined) //可以等同于我們寫了 return new Promise((resolve,reject)=>{resolve(/*原先的返回值*/)}) promise1.then(function (data) { console.log(data); return data; }, function (err) { console.error(err); return err; }).then(function (data) { console.log(data) }, function (err) { //這里是永遠不會被觸發(fā)的,原因是上一個.then() 返回的是new Promise((resolve,reject)=>{resolve(/*原先的返回值*/)}) //返回的Promise對象的reject方法永遠都不會被觸發(fā),所以這個里也就永遠都不會觸發(fā)了 console.error(err) });
講解都寫在注釋里面了,接下里我就貼運行圖吧,這段代碼會運行出以下兩類結(jié)果:
需要所有的請求都返回后才可以執(zhí)行某個動作
//改造promise,讓其可以接收一個定時器等待時間參數(shù) function promise(log, time) { return new Promise(function (resolve, reject) { setTimeout(function () { log = log || []; //和上次的例子一樣,利用隨機數(shù)來隨機失敗和成功 let num = Math.random(); if (num > 0.5) { log.push("等待時長" + time + "," + num + "大于0.5,這次異步操作失敗了"); console.error(log); reject(log) } else { log.push("等待時長" + time + "," + num + "小于0.5,這次異步操作成功了"); console.log(log); resolve(log) } }, time) }) } //Promise.all()可以接收一個Promise對象的數(shù)組,返回一個Promise對象 //該Promise對象會在數(shù)組中所有Promise成功返回后執(zhí)行成功回調(diào),在任意一個Promise失敗后立刻執(zhí)行失敗回調(diào) var promise1 = promise(null, 10), promise2 = promise(null, 100), promise3 = Promise.all([promise1, promise2]); promise3.then((data) => { //這里的data為promise1,和promise2的返回值的數(shù)組 console.log("promise3", data) }, (err, err2) => { //報錯信息 console.error("promise3", err) });
這段代碼一共有四種可能的結(jié)果
如果兩次都成功的話
如果兩次都成的話,promise3會執(zhí)行成功回調(diào),并且回調(diào)中的data就是promise1和promise2返回值的數(shù)組(數(shù)組順序和.all()中的順序一致)
任意一個promise失敗的話,promise3會立刻執(zhí)行失敗回調(diào),并且回調(diào)中的err就是失敗的那個promise在reject中返回的值
文章寫到這里,我認(rèn)為Promise常用的一些用法都已經(jīng)講完了,更詳細(xì)的Promise的教程請參考 MDN中對promise的講解
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/103568.html
摘要:單線程什么是單線程語言的執(zhí)行環(huán)境是單線程所謂單線程,就是指一次只能完成一件任務(wù)。如果有多個任務(wù),就必須排隊,前面一個任務(wù)完成,再執(zhí)行后面一個任務(wù),以此類推。 單線程 什么是單線程? Javascript語言的執(zhí)行環(huán)境是單線程(single thread) 所謂單線程,就是指一次只能完成一件任務(wù)。 如果有多個任務(wù),就必須排隊,前面一個任務(wù)完成,再執(zhí)行后面一個任務(wù),以此類推。 執(zhí)行JS代...
摘要:拋出的錯誤對象會被方法回調(diào)函數(shù)接收到命令命令后面是一個對象,返回該對象的結(jié)果。有人將其稱之為宏任務(wù)微任務(wù),定時器就屬于宏任務(wù)的范疇。 前言 上一篇 前端面試題-JavaScript(一), 感興趣的小伙伴也可以移步這里查看 完整版JavaScript面試題,面試題會不定期更新加進去一些個人工作中遇到的或者認(rèn)為比較重要的東西,后面會涉及到前端的各個方面,感興趣的小伙伴可以關(guān)注哦! 如果文...
摘要:面試題來源于網(wǎng)絡(luò),看一下高級前端的面試題,可以知道自己和高級前端的差距。 面試題來源于網(wǎng)絡(luò),看一下高級前端的面試題,可以知道自己和高級前端的差距。有些面試題會重復(fù)。 使用過的koa2中間件 koa-body原理 介紹自己寫過的中間件 有沒有涉及到Cluster 介紹pm2 master掛了的話pm2怎么處理 如何和MySQL進行通信 React聲明周期及自己的理解 如何...
摘要:的翻譯文檔由的維護很多人說,阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...
閱讀 3405·2021-11-08 13:12
閱讀 2934·2021-10-15 09:41
閱讀 1571·2021-10-08 10:05
閱讀 3431·2021-10-08 10:04
閱讀 2281·2021-09-29 09:34
閱讀 2643·2019-08-30 15:55
閱讀 3059·2019-08-30 15:45
閱讀 2714·2019-08-29 14:17