Promise专栏

Promise的常见问题
1、Promise解决了些什么问题
2、Promise在事件循环机制中的执行过程是怎样的
3、Promise常用的API有哪些
4、手写一个符合 Promise/A+ 规范的 Promise

1、Promise解决了些什么问题
在promise出现之前,想要拿到回调结果就必须得使用嵌套的方式,而且每一个任务处理都会有两种结果需要处理(失败和成功),这就是所谓的回调地狱,在代码维护上很艰难

let fs = require('fs')
fs.readFile('./name.txt','utf8',function(err,data){
  fs.readFile(data, 'utf8',function(err,data){
    fs.readFile(data,'utf8',function(err,data){
      console.log(data);
    })
  })
})

(1)**解决了嵌套的问题,**把第一个函数的输出作为下一个函数的输入,使用链式调用
(2)合并了多个任务的结果处理,.catch方法不管是上面哪个任务出现了异常都会进入到catch当中

2、Promise在事件循环机制中的执行过程是怎样的(链接

3、Promise的常用api
(1)对象方法
Promise.all()并发处理多个异步任务,所有任务都执行完成才能得到结果。
Promise.race()并发处理多个异步任务,只要有一个任务完成就能得到结果。
(2)实例方法
.then  得到异步任务的正确结果
.catch  获取异常信息
.finally  成功与失败都会执行

4、手写一个符合 Promise/A+ 规范的 Promise原链接

(1)then 的参数 onFulfilled 和 onRejected 可以缺省,如果 onFulfilled 或者 onRejected不是函数,将其忽略,且依旧可以在下面的 then 中获取到之前返回的值;「规范 Promise/A+ 2.2.1、2.2.1.1、2.2.1.2」
(2)promise 可以 then 多次,每次执行完 promise.then 方法后返回的都是一个“新的promise";「规范 Promise/A+ 2.2.7」
(3)如果 then 的返回值 x 是一个普通值,那么就会把这个结果作为参数,传递给下一个 then 的成功的回调中;
(4)如果 then 中抛出了异常,那么就会把这个异常作为参数,传递给下一个 then 的失败的回调中;「规范 Promise/A+ 2.2.7.2」
(5)如果 then 的返回值 x 是一个 promise,那么会等这个 promise 执行完,promise 如果成功,就走下一个 then 的成功;如果失败,就走下一个 then 的失败;如果抛出异常,就走下一个 then 的失败;「规范 Promise/A+ 2.2.7.3、2.2.7.4」
(6)如果 then 的返回值 x 和 promise 是同一个引用对象,造成循环引用,则抛出异常,把异常传递给下一个 then 的失败的回调中;「规范 Promise/A+ 2.3.1」
(7)如果 then 的返回值 x 是一个 promise,且 x 同时调用 resolve 函数和 reject 函数,则第一次调用优先,其他所有调用被忽略;「规范 Promise/A+ 2.3.3.3.3」

看几个promise的例子
第一题:第1秒红灯亮,第2秒黄灯亮,第3秒蓝灯亮;如何让三个灯不断交替重复亮灯?(用Promise实现)

function red() {
  console.log("red");
}
function green() {
  console.log("green");
}
function yellow() {
  console.log("yellow");
}
const light = function (timer, cb) {
  return new Promise(resolve => {
    setTimeout(() => {
      cb()
      resolve()
    }, timer)
  })
}
const step = function () {
  Promise.resolve().then(() => {
    return light(3000, red)
  }).then(() => {
    return light(2000, green)
  }).then(() => {
    return light(1000, yellow)
  }).then(() => {
    return step()
  })
}

step();

light 方法使用setTimeout做延时使用promise包裹的原因是,setTimeout属于一个宏任务,宏任务会交给其他延时线程处理然后加入到消息队列当中去,给事件循环机制来处理,如果在then方法中不return一个promise的而且什么都不return或者随便return一个值的话就会发生值的穿透,不会等延时执行完毕再去执行下一个then当中的内容。
这个题可以使用async和await来简洁一下

function light(color,delay){
	return new Promise((resolve,reject)=>{
		setTimeout(()=>{
			console.log(color);
			resolve();
		},delay)
	})
}
function async loop(){
	await light("red",1000);
	await light("yellow",1000);
	await light("green",1000);
	loop();
}
loop()

第二题:使用Promise实现每隔1秒输出1,2,3

let arr = [1,2,3];
arr.reduce((pre,item)=>{
	return pre.then(()=>{
		return new Promise((resolve,reject)=>{
			setTimeout(()=>{
				console.log(item)
				resolve()
			},1000)
		})
	})
},Promise.resolve())

这里的reduce的使用方式:

arr.reduce(callback,[initialValue])

callback (执行数组中每个值的函数,包含四个参数)

    1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
    2、currentValue (数组中当前被处理的元素)
    3、index (当前元素在数组中的索引)
    4、array (调用 reduce 的数组)

initialValue (作为第一次调用 callback 的第一个参数。)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值