摘要:那么如何使用它呢请看下面例子我是写在异步操作之后的操作总结通过控制台打印的内容可以看出,跟使用回调函数在结果上并没有什么异同。
今天我想说说说promise对象,说到这个对象就不能不提提异步操作,那么什么是异步操作,什么又是同步操作?
同步与异步操作区别同步操作的意思是在我们执行某个耗时比较长的操作的时候,下面的代码就会等待上面的代码执行完毕然后执行。说白了代码是顺序往下执行,某些操作执行的时间顺序和代码所在的行的顺序是相同的。请看下面获取一个txt文件的例子。
同步程序示例
首先,我们利用node先搭建一个服务器环境,默认获取1.html静态文件。代码如下:
let http = require("http"); let url = require("url"); let path = require("path"); let fs = require("fs"); http.createServer((req, res) => { var pathname = __dirname + url.parse(req.url).pathname; if (path.extname(pathname) === "") { pathname += "/"; } if (pathname.charAt(pathname.length - 1) === "/") { pathname += "1.html" } fs.exists(pathname, exists => { if (exists) { switch (path.extname(pathname)) { case ".html": res.writeHead(200, { "Content-type": "text/html" }); break; case ".js": res.writeHead(200, { "Content-type": "text/javascript" }); break; case ".jpg": res.writeHead(200, { "Content-type": "image/jpeg" }); break; case ".png": res.writeHead(200, { "Content-type": "image/png" }); case ".txt": res.writeHead(200, { "Content-type": "text/plain" }); break; case ".css": res.writeHead(200, { "Content-type": "text/css" }); break; default: ead res.writHead(200, { "Content-type": "application/octet-stream" }) } fs.readFile(pathname, (err, data) => { if (err) { console.log("read file error"); } else res.end(data); }) } }) }).listen(3000); console.log("server is runing...")
我们要从服务器用ajax获取txt文本数据。然后从客户端获取数据,如果这个操作是一个同步操作。如下所示
客户端获取数据代码
function showTxt(txt) { console.log(txt); } function getDocuments(url, cb) { let xhr = new XMLHttpRequest(); xhr.open("GET", url,false); xhr.send();、 cb(xhr.responseText); } getDocuments("1.txt", showTxt); console.log("我是获取文件之后执行的代码");
结果如下:
等这个获取文件这个操作执行完后,就会顺序执行接下来的代码。
这样的操作有什么问题呢?如果这个获取文件的代码耗时比较长,我们的程序就会卡死,下面的代码就不会执行下去,必须等获取文件代码执行完毕,解决问题的方法就是异步获取文件。那么什么是异步操作呢?说白了就是把获取文件的操作挂到另外一个线程,先执行后面的代码,上面的获取文件代码不会阻塞下面代码的运行。这两个操作是同时进行的。在以前,通常,如果是异步获取数据的,那么执行这个费时的获取数据操作时,会指定一个回调函数,当获取文件成功时触发处理结果的回调函数。在这个过程中,下面其他的代码会同时进行。把刚才获取文件的代码改成异步,请看下面代码。
异步获取数据程序示例
function showTxt(txt) { console.log(txt); } function getDocuments(url, cb) { let xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.send(); xhr.onreadystatechange = () => { if (xhr.status === 200 && xhr.readyState == 4) { cb(xhr.responseText); } else if (xhr.readyState === 4 && xhr.status !== 200) { console.log(`${xhr.status}get error`); } }; } getDocuments("1.txt", showTxt); console.log("我是获取文件后执行的代码");
![图片描述][2]
可以看出先执行了下面的代码然后执行了ajax获取文件回调函数里面的代码,证明了下面的其他操作的代码会与获取文件操作同时执行。这就是异步操作与同步操作的区别
promise对象有什么用处?由上面示例可以看到如果是一个异步操作的代码,通常,我们就需要为它指定回调函数,例如上面的代码回调函数就是onreadystatechange当它的状态码变成4,收到服务器响应,我们拿到数据后再执行下步操作,先把它挂起来,让下面的的代码运行。但是如果因果关系变得复杂,回调事件变得很多,我们的代码就会变得十分像一个向右的金字塔结构不利于阅读。
promise对象巧妙的解决了这个问题,把回调函数变成了链式调用,更加符合代码书写习惯。那么如何使用它呢?
function getTxt(url) { let p = new Promise((resolve, reject) => { let xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.send(); xhr.onreadystatechange = () => { if (xhr.readyState !== 4) { return; } if (xhr.status === 200) { resolve(xhr.responseText); } else { reject(`${xhr.status}get error`); } } }); return p; } getTxt("1.txt").then(showTxt).catch((error) => { console.log(error); }); console.log("我是写在异步操作之后的操作")
总结
通过控制台打印的内容可以看出,跟使用回调函数在结果上并没有什么异同。但是代码结构更加清晰化,并且可以catch到错误信息。
1.先new 一个promise对象,然后给它的参数传递一个回调函数进去,回调函数里面有两个参数resolve,reject都是函数。
2.resolve函数是把异步状态变成成功,可以把异步结果作为它的参数传递到then的回调函数参数中,而then方法会在promise状态成功时候调用;3.reject函数可以把promise状态变成失败,当异步请求状态失败时调用,可以传递出去错误信息,这个会触发promise对象上的catch方法,通过promise对象的catch方法的回调函数的参数捕获该错误信息。最后返回该promise对象实现链式调用。这就是promise对象的基本用法。
4.当然它还有all, race,resolve,reject等各种实例方法和静态方法,不过上面的用法时最经常见到的,最基础的。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/83195.html
摘要:从最开始的到封装后的都在试图解决异步编程过程中的问题。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。写一个符合规范并可配合使用的写一个符合规范并可配合使用的理解的工作原理采用回调函数来处理异步编程。 JavaScript怎么使用循环代替(异步)递归 问题描述 在开发过程中,遇到一个需求:在系统初始化时通过http获取一个第三方服务器端的列表,第三方服务器提供了一个接口,可通过...
摘要:引擎线程也称为内核,负责处理脚本程序例如引擎引擎线程负责解析脚本,运行代码。对象代表一个未完成但预计将来会完成的操作。注意一旦新建就会立即执行它属于,无法取消。 写在前面: 第一遍学Promise时, 只是大概过了一遍, 感觉学的不够深入, 这一篇算是对之前的一个总结吧. Promise在ES6中也属于一个较难理解的一部分; 所以在学习一个比较难理解的知识点时, 我们可以围绕这个知识点...
摘要:单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这决定了它只能是单线程,否则会带来很复杂的同步问题。小结本身是单线程的,并没有异步的特性。当异步函数执行时,回调函数会被压入这个队列。 走在前端的大道上 本篇将自己读过的相关 js异步 的文章中,对自己有启发的章节片段总结在这(会对原文进行删改),会不断丰富提炼总结更新。 概念 JS 是单线程的语言。 单线程就意味着...
摘要:单线程什么是单线程语言的执行环境是单线程所谓单线程,就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。 单线程 什么是单线程? Javascript语言的执行环境是单线程(single thread) 所谓单线程,就是指一次只能完成一件任务。 如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。 执行JS代...
摘要:则是把类似的异步处理对象和处理规则进行规范化,并按照采用统一的接口来编写,而采取规定方法之外的写法都会出错。这个对象有一个方法,指定回调函数,用于在异步操作执行完后执行回调函数处理。到目前为止,已经学习了创建对象和用,方法来注册回调函数。 Promise 本文从js的异步处理出发,引入Promise的概念,并且介绍Promise对象以及其API方法。 js里的异步处理 可以参考这篇文章...
阅读 2128·2021-09-27 14:04
阅读 1873·2019-08-30 15:55
阅读 1698·2019-08-30 13:13
阅读 1065·2019-08-30 13:07
阅读 2741·2019-08-29 15:20
阅读 3239·2019-08-29 12:42
阅读 3323·2019-08-28 17:58
阅读 3593·2019-08-28 17:56