处理异步操作演变详解:回调函数、Promise、Generator、async和await

处理异步操作演变

回调函数==>Promise对象==>Genarator函数==>async和await

回调函数

客户端JS在浏览器是单线程运行,会将同步任务先执行完毕再执行异步任务以保证运行过程不阻塞,但有时我们在调用一个同步任务前需要拿到上一个异步任务的结果,所以需要回调函数帮助实现。

 <script>
        function getMessage(msg,callback){
    
    
            setTimeout(() => {
    
    
                console.log(msg);
                callback();
            }, 2000);
        }
        function waitMe(){
    
    
            console.log("wait me!");
        }
        getMessage("helloYokia",waitMe)

    </script>
回调函数缺点:
  • 本质是嵌套函数,但代码严重藕合,不利于查看和修改。
  • 修改错误很艰难,不能捕捉和return错误结果。

Promise对象

优点:
  • 解决了回调地狱层层嵌套的问题。
缺点

但.then.then的链式操作也很复杂,而且还要新建一个new Promise来处理相应(相当于家里专门请来个保姆),并且把数据赋值给一个新变量。
举个promise使用的小栗子:
不请保姆了,我亲自把我脑海中的一系列想法一一实现:
我要织围巾送人!

 function 买材料(resolve,reject) {
    
    
            setTimeout(function () {
    
    
                resolve(['毛线', '毛线针']);
            }, 3000)
        }
        function 织围巾(resolve, reject) {
    
    
            setTimeout(function () {
    
    
                //用买到的材料开始织围巾
                resolve({
    
    
                    成品: '围巾',
                    附加品: '一封信',
                    打包: "礼物盒包装一下"
                })
            }, 3000)
        }
        function 送礼物(resolve,reject) {
    
    
            //对送礼物的结果进行下一步处理
            resolve('某人感动的稀里哗啦');
        }
        function 回礼() {
    
    
            //回礼后的下一步处理
            resolve('我得到了一枚鹅蛋大的钻戒吼吼吼~')
        }

想法结束,付诸行动!

new Promise(买材料)
//用材料织围巾
.then((材料)=>{
    
    
    return new Promise(织围巾);
})
.then((围巾)=>{
    
    
    return new Promise(送出礼物);
})
.then((感动&痛哭)=>{
    
    
    回礼();
}).catch(err => {
    
    
    console.log(err);
});

另外,中间任何一步出错都可以在最后.catch捕捉到并输出。

三种状态
  • pending:正在执行
  • resolve:成功的回调函数
  • reject:失败的回调函数
    (promise的状态只能改变一次。)
promise常用api
  • Promise.reject

类方法,且与 resolve 唯一的不同是,返回的 promise 对象的状态为 rejected。

  • Promise.prototype.then

实例方法,为 Promise 注册回调函数 fn(vlaue){},value 是上一个任务的返回结果,then 中的函数一定要 return 一个结果或者一个新的 Promise 对象,才可以让之后的then 回调接收。
注意:后续任务如果是异步任务,需要用new Promise对象来返回,同步用return。

  • Promise.prototype.catch

实例方法,捕获异常,函数形式:fn(err){}, err 是 catch 注册之前的回调抛出的异常信息。

  • Promise.race

类方法,多个 Promise 任务同时执行,返回最先执行结束的 Promise 任务的结果,不管这个 Promise 结果是成功还是失败。

  • Promise.all

类方法,多个 Promise 任务同时执行。
如果全部成功执行,则以数组的方式返回所有 Promise 任务的执行结果。 如果有一个 Promise 任务 rejected,则只返回 rejected 任务的结果。

Generator

简单的generator函数

function* g() {
    
    
    yield 'a';
    yield 'b';
    yield 'c';
    return 'ending';
}

var gen = g();
gen.next(); // 返回Object {
    
    value: "a", done: false}
gen.next(); // 返回Object {
    
    value: "a", done: false}
gen.next(); // 返回Object {
    
    value: "a", done: false}
gen.next(); // 返回Object {
    
    value: "ending", done: true}
//return后再写一行 没有意义
gen.next(); //{
    
    value: undefined, done: true}

generator翻译:生产器;yield翻译:产出

Generator 函数的特点就是:

1、分段执行,可以暂停
2、可以控制阶段和每个阶段的返回值
3、可以知道是否执行到结尾

async await

async testAsync() {
    
    
  try {
    
    
     await getJSON()
  } catch(err) {
    
    
     console.log(err)
  }
  ...剩下的代码
}

猜你喜欢

转载自blog.csdn.net/weixin_47067248/article/details/109946687