日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Promise学习——解决回调地狱问题

發布時間:2024/7/5 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Promise学习——解决回调地狱问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Promise

promise 容器概念:

callback hell(回調地獄):

文件的讀取無法判斷執行順序(文件的執行順序是依據文件的大小來決定的)(異步api無法保證文件的執行順序)

var fs = require('fs');fs.readFile('./data/a.text','utf8',function(err,data){if(err){// 1 讀取失敗直接打印輸出讀取失敗return console.log('讀取失敗');// 2 拋出異常// 阻止程序的執行// 把錯誤信息打印到控制臺throw err;}console.log(data); });fs.readFile('./data/b.text','utf8',function(err,data){if(err){// 1 讀取失敗直接打印輸出讀取失敗return console.log('讀取失敗');// 2 拋出異常// 阻止程序的執行// 把錯誤信息打印到控制臺throw err;}console.log(data); });

通過回調嵌套的方式來保證順序:

var fs = require('fs');fs.readFile('./data/a.text','utf8',function(err,data){if(err){// 1 讀取失敗直接打印輸出讀取失敗return console.log('讀取失敗');// 2 拋出異常// 阻止程序的執行// 把錯誤信息打印到控制臺throw err;}console.log(data);fs.readFile('./data/b.text','utf8',function(err,data){if(err){// 1 讀取失敗直接打印輸出讀取失敗return console.log('讀取失敗');// 2 拋出異常// 阻止程序的執行// 把錯誤信息打印到控制臺throw err;}console.log(data);fs.readFile('./data/a.text','utf8',function(err,data){if(err){// 1 讀取失敗直接打印輸出讀取失敗return console.log('讀取失敗');// 2 拋出異常// 阻止程序的執行// 把錯誤信息打印到控制臺throw err;}console.log(data);});}); });

為了解決以上編碼方式帶來的問題(回調地獄嵌套),所以在EcmaScript6新增了一個API:Promise。

  • Promise:承諾,保證
  • Promise本身不是異步的,但往往都是內部封裝一個異步任務

基本語法:

var fs = require('fs') // 在EcmaScript 6 中新增了一個API Promise // Promise 是一個構造函數// 創建 Promise 容器 // 1.給別人一個承諾 I promise you // Promise 容器一旦創建,就開始執行里面的代碼 var p1 = new Promise(function(resolve, reject) {fs.readFile('./data/a.txt', 'utf-8', function(err, data) {if (err) {// 失敗了,承諾容器中的任務失敗了// console.log(err)// 把容器的Pending狀態變為Rejected// 調用的reject方法實際上就是then方法傳遞的第二個參數函數functionreject(err)} else {// 承諾容器中的任務成功了// console.log(data)// 把容器的Pending狀態變為成功// 也就是說這里調用的resolve方法實際上就是then方法傳遞的第一個functionresolve(data)}}) })// p1 就是那個承諾 // 當 p1 成功了,然后(then)做指定的操作 // then 方法接收的function就是容器中的resolve函數 p1.then(function(data) {console.log(data) }, function(err) {console.log('讀取文件失敗', err) })

鏈式循環:

封裝Promise的readFile:

var fs = require('fs')function pReadFile(filePath) {return new Promise(function(resolve, reject) {fs.readFile(filePath, 'utf-8', function(err, data) {if (err) {reject(err)} else {resolve(data)}})}) }pReadFile('./data/a.txt').then(function(data) {console.log(data)return pReadFile('./data/b.txt')}).then(function(data) {console.log(data)return pReadFile('./data/c.txt')}).then(function(data) {console.log(data)})

var fs = require('fs') // 在EcmaScript 6 中新增了一個API Promise // Promise 是一個構造函數// 創建 Promise 容器 // 1.給別人一個承諾 I promise you // Promise 容器一旦創建,就開始執行里面的代碼 var p1 = new Promise(function(resolve, reject) {fs.readFile('./data/a.txt', 'utf-8', function(err, data) {if (err) {// 失敗了,承諾容器中的任務失敗了// console.log(err)// 把容器的Pending狀態變為Rejected// 調用的reject方法實際上就是then方法傳遞的第二個參數函數functionreject(err)} else {// 承諾容器中的任務成功了// console.log(data)// 把容器的Pending狀態變為成功// 也就是說這里調用的resolve方法實際上就是then方法傳遞的第一個functionresolve(data)}}) })var p2 = new Promise(function(resolve, reject) {fs.readFile('./data/b.txt', 'utf-8', function(err, data) {if (err) {reject(err)} else {resolve(data)}}) })var p3 = new Promise(function(resolve, reject) {fs.readFile('./data/c.txt', 'utf-8', function(err, data) {if (err) {reject(err)} else {resolve(data)}}) })// p1 就是那個承諾 // 當 p1 成功了,然后(then)做指定的操作 // then 方法接收的function就是容器中的resolve函數 p1.then(function(data) {console.log(data)// 當 p1讀取成功的時候// 當前函數中 return 的結果就可以在后面的 then中function接收到// 當return 一個 promise 對象的時候,后續的then中的方法的第一個參數會作為p2 的resolvereturn p2 }, function(err) {console.log('讀取文件失敗', err) }).then(function(data) {console.log(data)return p3 }).then(function(data) {console.log(data) })

需求:分別向兩個接口:users和jobs發送請求,獲取響應數據,將數據通過art-template 模板渲染到html頁面上

第一種:使用自己封裝的callback方式

data.json:

{"users": [{"id": 1,"username": "admin","age": 22,"job": 4},{"id": 2,"username": "admin2","age": 18,"job": 1},{"id": 3,"username": "admin3","age": 18,"job": 1}],"jobs": [{"id": 1,"name": "學生"},{"id": 2,"name": "老師"},{"id": 3,"name": "司機"},{"id": 4,"name": "演員"},{"id": 5,"name": "畫家"},{"id": 6,"name": "電競人"}] }

這里使用json-server來開啟一個服務:
首先,安裝 json-server: npm install -g json-server

然后通過命令:json-server --watch data.json啟動服務:


由于用到了模板引擎來將數據渲染到頁面上,所以需要再安裝一個art-template包:
npm i art-template

<!DOCTYPE html> <html><head><meta charset="utf-8"><title></title></head><body><form action="#" id="user_form"></form><script type="text/text/template" id="tpl"><label for="">用戶名</label><input type="text" value="{{ user.username }}"><label for="">年齡</label><input type="text" value="{{ user.age }}"><label for="">職業</label><select name="" id="">{{ each jobs }}{{ if user.job === $value.id }}<option value="{{ $value.id }}" selected="selected">{{ $value.name }}</option>{{ else }}<option value="{{ $value.id }}">{{ $value.name }}</option>{{ /if }} {{ /each }}</select> </script><script src="node_modules/art-template/lib/template-web.js"></script><script>// 用戶表// 其中一個接口獲取用戶數據// 職業:1// 職業信息表// 其中一個接口獲取所有的職業信息get('http://127.0.0.1:3000/users/1', function(userData) {// data = JSON.parse(data)get('http://127.0.0.1:3000/jobs', function(jobsData) {// console.log(userData, jobsData)var htmlStr = template('tpl', {user: JSON.parse(userData),jobs: JSON.parse(jobsData)})console.log(htmlStr)document.querySelector('#user_form').innerHTML = htmlStr})})function get(url, callback) {var oReq = new XMLHttpRequest()// 當請求加載成功之后要調用指定的函數oReq.onload = function() {// 我現在需要得到這里的 oReq.responseTextcallback(oReq.responseText)}oReq.open("get", url, true)oReq.send()}</script></body> </html>

第二種:使用jquery的promise方式

<!DOCTYPE html> <html><head><meta charset="utf-8"><title></title></head><body><form action="#" id="user_form"></form><script type="text/text/template" id="tpl"><label for="">用戶名</label><input type="text" value="{{ user.username }}"><label for="">年齡</label><input type="text" value="{{ user.age }}"><label for="">職業</label><select name="" id="">{{ each jobs }}{{ if user.job === $value.id }}<option value="{{ $value.id }}" selected="selected">{{ $value.name }}</option>{{ else }}<option value="{{ $value.id }}">{{ $value.name }}</option>{{ /if }} {{ /each }}</select> </script><script src="node_modules/jquery/dist/jquery.js"></script><script src="node_modules/art-template/lib/template-web.js"></script><script>// 用戶表// 其中一個接口獲取用戶數據// 職業:1// 職業信息表// 其中一個接口獲取所有的職業信息/* get('http://127.0.0.1:3000/users/1', function(userData) {// data = JSON.parse(data)get('http://127.0.0.1:3000/jobs', function(jobsData) {// console.log(userData, jobsData)var htmlStr = template('tpl', {user: JSON.parse(userData),jobs: JSON.parse(jobsData)})console.log(htmlStr)document.querySelector('#user_form').innerHTML = htmlStr})}) */var data = {}$.get('http://127.0.0.1:3000/users/1').then(function(userData) {console.log(userData)data.user = userDatareturn $.get('http://127.0.0.1:3000/jobs')}).then(function(jobsData) {console.log(jobsData)data.jobs = jobsDataconsole.log(data)var htmlStr = template('tpl', data)console.log(htmlStr)document.querySelector('#user_form').innerHTML = htmlStr})function get(url, callback) {var oReq = new XMLHttpRequest()// 當請求加載成功之后要調用指定的函數oReq.onload = function() {// 我現在需要得到這里的 oReq.responseTextcallback(oReq.responseText)}oReq.open("get", url, true)oReq.send()}</script></body> </html>

3.用promise封裝ajax版:

<!DOCTYPE html> <html><head><meta charset="utf-8"><title></title></head><body><form action="#" id="user_form"></form><script type="text/text/template" id="tpl"><label for="">用戶名</label><input type="text" value="{{ user.username }}"><label for="">年齡</label><input type="text" value="{{ user.age }}"><label for="">職業</label><select name="" id="">{{ each jobs }}{{ if user.job === $value.id }}<option value="{{ $value.id }}" selected="selected">{{ $value.name }}</option>{{ else }}<option value="{{ $value.id }}">{{ $value.name }}</option>{{ /if }} {{ /each }}</select> </script><script src="node_modules/jquery/dist/jquery.js"></script><script src="node_modules/art-template/lib/template-web.js"></script><script>// 用戶表// 其中一個接口獲取用戶數據// 職業:1// 職業信息表// 其中一個接口獲取所有的職業信息/* get('http://127.0.0.1:3000/users/1', function(userData) {// data = JSON.parse(data)get('http://127.0.0.1:3000/jobs', function(jobsData) {// console.log(userData, jobsData)var htmlStr = template('tpl', {user: JSON.parse(userData),jobs: JSON.parse(jobsData)})console.log(htmlStr)document.querySelector('#user_form').innerHTML = htmlStr})}) */ /* var data = {}$.get('http://127.0.0.1:3000/users/1').then(function(userData) {console.log(userData)data.user = userDatareturn $.get('http://127.0.0.1:3000/jobs')}).then(function(jobsData) {console.log(jobsData)data.jobs = jobsDataconsole.log(data)var htmlStr = template('tpl', data)console.log(htmlStr)document.querySelector('#user_form').innerHTML = htmlStr}) */var data = {}get('http://127.0.0.1:3000/users/1').then(function(userData) {data.user = userDatareturn $.get('http://127.0.0.1:3000/jobs')}).then(function(jobsData) {data.jobs = jobsDatavar htmlStr = template('tpl', data)document.querySelector('#user_form').innerHTML = htmlStr }) function get(url) {return new Promise(function(resolve, reject) {var oReq = new XMLHttpRequest()// 當請求加載成功之后要調用指定的函數oReq.onload = function() {// 我現在需要得到這里的 oReq.responseTextresolve(JSON.parse(oReq.responseText))} oReq.onerror = function (err) {reject(err)}oReq.open("get", url, true)oReq.send()})}/* function get(url, callback) {var oReq = new XMLHttpRequest()// 當請求加載成功之后要調用指定的函數oReq.onload = function() {// 我現在需要得到這里的 oReq.responseTextcallback(oReq.responseText)}oReq.open("get", url, true)oReq.send()} */</script></body> </html>

mongoose所有的API都支持Promise:

// 查詢所有 User.find().then(function(data){console.log(data)})

注冊:

User.findOne({username:'admin'},function(user){if(user){console.log('用戶已存在')} else {new User({username:'aaa',password:'123',email:'fffff'}).save(function(){console.log('注冊成功');})} }) User.findOne({username:'admin' }).then(function(user){if(user){// 用戶已經存在不能注冊console.log('用戶已存在');}else{// 用戶不存在可以注冊return new User({username:'aaa',password:'123',email:'fffff'}).save();}}).then(funciton(ret){console.log('注冊成功');})

Generator

async函數

總結

以上是生活随笔為你收集整理的Promise学习——解决回调地狱问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。