异步编程(Promise实现同步处理任务原理)

今天的这篇文章主要是总结promise对象如何实现同步处理异步任务:

我从头开始慢慢介绍这个过程吧!这个过程我会用代码一一实现,毕竟文字不如 代码来得合适。

promise的三种状态

//pending 准备阶段
//fulfilled 成功
//rejected  失败
function promise() {
    return new Promise((resolve, reject) => {
        resolve("成功");
        // reject("失败");
    })
}
console.log(promise()); //Promise {<pending>} 没调用微任务之前
// console.log(promise()); // Promise {<fulfilled>: "成功"} 调用resolve
// console.log(promise()); //Promise {<rejected>: "失败"} 调用reject

Promise对象的任务进行抛出(一般我们就定义reslove成功reject失败)并通过thencatch关键字进行处理:

//可以将任务处理模块(resolve或reject)多次抛出
//以then或者catch结束(必须有处理模块,放一个空的then是无效的)来获取这个结果并会结束此次任务
let p1 = new Promise((resolve, reject) => {
    // resolve("成功");
    reject("失败")
})
new Promise((resolve, reject) => {
    resolve(p1)
}).then(
    value => {
        console.log(value);
    },
    reason => {
        console.log("error" + reason);
    }
).catch(error => {
    console.log(error); //这里不能再次获取失败内容,因为在上面已获取了一次了
})

我们要记住默认情况下.then返回的promise对象抛出的是成功状态

let p1 = new Promise((resolve, reject) => {
    // resolve("fulfilled");
    reject("reject");
});
//可以通过一个变量存储p1这个promise对象
let p2 = p1
.then(
    value => console.log("成功" + value),
    error => console.log("失败" + error)
)
.then(
    //会输出 但不会得到a值,它是undefined,因为在上面已经接受了
    a => console.log("最后的成功" + a), //最后的成功undefined
    //不会执行,默认情况下.then返回的是成功的,只会打印resolve语句
    b => console.log("最后的失败" + b)
).then(
    //依旧会执行 a此时为undefined
    a => console.log("11" + a) //11undefined
)

总之一句话,.then就是对返回的前一个promise对象进行处理,默认.then返回的是成功的promise对象

let p1 = new Promise((resolve, reject) => {
   resolve("第一次成功");
});
p1.then(
    // value => 123, //这里可以是一个返回值,让下一个then去处理这个值
    //当然这里也可以嵌套一个promise对象
    value => {
        console.log(value); //接受第一次成功
        return new Promise((resolve, reject) => {
            resolve("第二次成功")
        })
    },
    error => console.log(error) //不会输出 没有错误reject抛出
).then(
    //通过这样来处理前面的返回值
    //实现了嵌套promise对象的模块
    res => console.log("拿到前面的返回值" + res), //拿到前面的返回值第二次成功
    err => console.log(err) //对前面返回值中抛出错误处理
)

好了我们可以稍稍深入一点点了,我们从上面的代码也能看出,异步任务是可以通过Promise对象去使之变成同步任务的,我们可以把这些同步任务称为队列,下面的代码或许更加明朗一些:

let promise = Promise.resolve("123"); //下面有介绍哦
promise = promise.then(
    value => {
        return new Promise(resolve => {
            setTimeout(() => {
                console.log(value);
                resolve("ab")
            }, 1000);
        })

    }
);
//实际得到就是上一个promise返回值赋值给一个变量罢了 跟直接用then差不多的
promise.then(
    v => {
        return new Promise(resolve => {
            setTimeout(() => {
                console.log(v);
                resolve("ab")
            }, 1000);
        })
    }
)

上述Promise.resolve("123");实际上就是以下代码的简写了,可以试试看,得出来的结果是一样的:

new Promise(resolve => {
	reslove("123");
}.then(
	res => console.log(res);  //"123"
)

Promise.resolve("123").then(res => console.log(res)) //"123"

这里的原理要理解清楚,下面就是对其的拓展了;

----------------数组实现队列(相当于同步任务,依次执行)
其实这也是一个异步任务:
数组map方式实现:

let arr = [1, 2, 3, 4, 5];
//封装成函数 map方式 封装队列
function queue(arr) {
    let promise = Promise.resolve();
    //循环给promise赋值,使其同步输出
    arr.map(v => {
        promise = promise.then(_ => {
            return new Promise(resolve => {
                setTimeout(() => {
                    console.log(v); //这里会依次去打印1,2,3,4,5每次间隔时间为1秒
                    resolve();
                }, 1000)
            })
        }
        )
    })
}
queue(arr);

这样写的话,我们大大减少了之前用链式then依次输出的代码量,而且我感觉这样的代码看起来还是有点牛皮哈! 哈哈

reduce实现队列:其核心跟map是差不多的,需要了解这种方法的使用,不清楚的伙伴可以去看数组的八种遍历方式

//使用reduce 封装队列
let arr = [1, 2, 3, 4, 5];
arr.reduce((promise, n) => {
    return promise.then(_ => {
        return new Promise(resolve => {
            setTimeout(() => {
                console.log(n); //这里也会依次去打印1,2,3,4,5每次间隔时间为1秒
                resolve()
            }, 1000)
        })
    })
}, Promise.resolve())

好了,文章就到此结束了,这个也是偶然看视频获得一些总结,希望大家多多支持啊!!!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值