美文网首页
理解Promise, async, await

理解Promise, async, await

作者: 江ls | 来源:发表于2020-12-11 15:20 被阅读0次

    关于异步

    JavaScript脚本执行是“单线程”(脚本解释引擎是单线程的),但会GUI线程,网络请求线程等
    JS引擎基于事件驱动,内部维持一个执行循环的任务,持续读取回调队列的任务。

    任务分为同步任务和异步任务:

    • 同步任务是指在主线程排队执行的任务,只有前一个执行完毕,后一个才会执行。
    • 异步任务是指由运行环境执行,任务完成后,将事先定义的回调函数推入主线程的任务队列,当主线程的执行栈清空之后会读取任务队列的回到函数,当任务队列被读取完毕之后,主线程接着执行,从而进入一个无限循环,这就是事件循环。

    异步任务队列分为:
    macro-task: script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering
    micro-task: process.nextTick, Promises(这里指浏览器实现的原生 Promise), Object.observe, MutationObserver

    一个事件循环,多个任务队列

    t01134d053300881c3b.png

    每一次事件循环(one cycle of the event loop),只处理一个 (macro)task。待该 macrotask 完成后,所有的 microtask 会在同一次循环中处理

    关于Promise

    Promise是一个函数返回的对象,代表一个异步操作的完成或失败。
    Promise链式调用风格,每一个 Promise 都代表了链中另一个异步过程的完成,避免callback形式的嵌套调用。一种用处,串行异步任务调用,传递上个异步任务结果。

    (function simple () {
        // 创建Promise对象,Promise参数传入的是一个函数,此函数有resolve, reject 两个参数
        let promise = new Promise((resolve, reject) => {
            // 调用resolve, resolve是Promise内定义的函数,切换当前Promise从 'pending' 到 'fulfilled' 状态
            setTimeout(() => resolve('Success'), 2000)
        });
        // 添加解决(fulfillment)和拒绝(rejection)回调到当前 promise, 返回一个新的 promise, 将以回调的返回值来resolve.
        // onResolved函数的参数就是上面resolve传入的参数
        promise .then((msg) => {
            console.log(`Hello Message is ${msg}`)
        }, () => {
            console.log('oops! its rejected')
        })
    }())
    
    参考模拟实现源码:https://github.com/xieranmaya/Promise3/blob/master/Promise3.js
    

    链式调用中的 promise 们就像俄罗斯套娃一样,是嵌套起来的,但又像是一个栈,每个都必须从顶端被弹出。链式调用中的第一个 promise 是嵌套最深的一个,也将是第一个被弹出的。

    const myPromise =
      (new Promise(myExecutorFunc))
      .then(handleFulfilledA,   handleRejectedA)
      .then(handleFulfilledB)
      .then(handleFulfilledC, handleRejectedC)
      .then(handleFulfilledD, handleRejectedD)
      .catch(handleRejectedAny);
    
    // (promise D, (promise C, (promise B, (promise A) ) ) )
    
    promises.png

    关于async和await

    async和await是Promise的语法糖,比使用Promise更易写和易读

    // 用async关键词后,hello()将是一个返回Promise的异步函数
    async function hello() { return "Hello" };
    hello();
    
    // 输出   ƒ AsyncFunction() { [native code] }
    console.log(Object.getPrototypeOf(async function(){}).constructor)
    

    实际例子

    // Promise写法
    fetch('coffee.jpg')
    .then(response => {
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      } else {
        return response.blob();
      }
    })
    .then(myBlob => {
      let objectURL = URL.createObjectURL(myBlob);
      let image = document.createElement('img');
      image.src = objectURL;
      document.body.appendChild(image);
    })
    .catch(e => {
      console.log('There has been a problem with your fetch operation: ' + e.message);
    });
    
    // await写法
    async function myFetch() {
      let response = await fetch('coffee.jpg');
    
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      } else {
        let myBlob = await response.blob();
    
        let objectURL = URL.createObjectURL(myBlob);
        let image = document.createElement('img');
        image.src = objectURL;
        document.body.appendChild(image);
      }
    }
    
    myFetch()
    .catch(e => {
      console.log('There has been a problem with your fetch operation: ' + e.message);
    });
    

    参考:
    https://www.cnblogs.com/10yearsmanong/p/12212512.html
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
    https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await

    相关文章

      网友评论

          本文标题:理解Promise, async, await

          本文链接:https://www.haomeiwen.com/subject/idxobktx.html