大家好,欢迎来到IT知识分享网。
关于promise的基础知识
在接触到promise时,我自己也是一脸懵,所以两天学完后,想做一个总结关于它。
一、异步编程的背景知识
–javascript引擎是单线程时间循环的概念构建的,同一时刻只能执行一个代码块,所以需要跟踪即将运行的代码,那些代码被放在一个任务队列里,每当一段代码准备执行时,都会被添加到任务队列,每当一段代码结束执行,时间循环会执行队列中的下一个任务,队列中的任务都会从第一个执行到最后一个。
*事件模型
*回调模式
–node.js通过普及回调函数来改进异步编程模式,与事件模型类似,异步代码会在未来的某个时间点执行,二者的区别是回调模式中被调用的函数是作为参数传入的。例如
readfile("example.txt",function(err,contents){ if(err){ throw err; } conole.log(contents); }); console.log('Hi!');
虽然这个回调比事件模型更加的灵活,但是如果要实现复杂的功能,比如并行执行两个或多个异步操作,就需要跟踪多个回调函数并清理这些操作,比较复杂,所以这个时候,promise的用处就体现出来了。它可以把原来的回调函数分离出来,在异步操作执行完成后,用链式调用的方法执行回调函数。
二、promise的基础知识
promise相当于异步操作结果中的占位符,它不会去订阅一个事件,也不会传递一个回调函数给目标函数,而是让函数返回一个promise,实质上promise是一个构造函数。
promise表面上看是简化层层回调的方法,实质上它的精髓在于”状态”,用维护状态,传递状态的方式来使得回调函数可以及时的调用,它比传递callback更加的简单、灵活。
1、promise的生命周期
先是处于进行中(pending)的状态,也是未处理的状态,一旦异步操作结束后,可能进入到以下两个状态的一种:
- Fulfilled promise异步操作完成
- Rejected 由于程序错误或一些其他的原因,异步操作未完成。
– 内部属性[PromiseState]被用来表示promise的三种状态:“pending”、“fulfilled”、“rejected”,因为这个属性不暴露在属性里,所以不能用编程的方式检测promise的状态,所以只有当promise的状态改变时,通过then()方法采取特定的行动。
2、静态方法
(1)、then()
所有的promise都有then()方法,它接收两个参数:第一个时promise的状态变成fulfilled时要调用的函数,与异步操作相关的附加数据都会传递给这个词完成函数,第二个是当promise的状态变成rejected时要调用的函数,所有与失败状态相关的附加数据都会传递给这个拒绝函数。
function getNumber(){ var p = new Promise(function(resolve, reject){ //做一些异步操作 setTimeout(function(){ var num = Math.ceil(Math.random()*10); //生成1-10的随机数 if(num<=5){ resolve(num); } else{ reject('数字太大了'); } }, 2000); }); return p; } getNumber() .then( function(data){ console.log('resolved'); console.log(data); }, function(reason, data){ console.log('rejected'); console.log(reason); } );
getNumber函数用来异步获取一个数字,2秒后执行完成,如果数字小于等于5,我们认为是“成功”了,调用resolve修改Promise的状态。否则我们认为是“失败”了,调用reject并传递一个参数,作为失败的原因。
(2)、catch()方法
promise.catch(function(err){ //拒绝 console.log(err.message); }); //与下面的调用一致 promise.then(null,function(err){ //拒绝 console.log(err.message); });
2、创建未完成的promise
let fs = require('fs'); function readFile(filename){ return new Promise(function(resolve,reject){ //触发异步操作 fs.readFile(filename,{encoding:"utf-8"},function(err,contents){ //检查是否有错误 if(err){ reject(err); return; } //成功读取文件 resolve(contents); }); }); } let promise = readFile('example.txt'); //同时监听执行完成和执行被拒 promise.then(function(contents){ //完成 console.log(contents); },function(err){ console.log(err.message); });
当readFile()方法被调用时,执行器会立即执行,这里有一种任务编排的过程,类似于setTimeout()和setInterval()函数,在这里—————->
promise的执行器会立即执行,然后在执行后续的代码
具体看下面的这个例子:
let promise= new Promise(function(resolve,reject){ console.log("promise"); resolve(); }); promise.then(function(){ console.log('resolved'); }); console.log('hi~~!')
执行的结果如下:
原理分析:当调用resolve()时会触发一个异步操作,传入then()和catch()方法的函数会被添加到任务队列中并异步执行,这个例子虽然then()在consol.log(‘hi`~~!);之前,但其与执行器不同,所以并没有立即执行,原因在于:完成处理程序和拒绝处理程序总是在执行器完成后被添加到任务队列的末尾。
3、创建已处理的promise
以下两种方法可以根据特定的值来创建已解决promise:
(1)使用promise.resolve()
该方法只接受一个参数并返回一个完成态的promise,不会有任务编排过程,需要向promise添加一个或多个完成处理程序来获取值。例如:
let promise= Promise。resolve(42); promise.then(function(value){ console.log(value); //42 });
因为该promise永远不存在拒绝状态,所以该promise的拒绝处理程序永远不会调用。
(2)使用promise.reject()
通过该方法来创建已拒绝promise,该promise不会调用完成处理程序。
若向上述方法传入一个promise,那么这个promise会直接被返回!
4、执行器错误
如果执行器内部抛出一个错误,则promise的拒绝处理程序就会被调用,每个执行器都隐含着一个try-catch块。———?执行器会捕获所有的错误但只有当拒绝处理程序存在时才会记录执行器中抛出的错误,否则会被忽略。
四、响应多个promise
1、promise.all()方法
2、promise.race()方法
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/116905.html
