首页 > 其他分享 >4.Promise

4.Promise

时间:2023-03-04 20:12:54浏览次数:32  
标签:协程 函数 生成器 Promise 执行 gen

1.什么是promise

Promise是异步编程的一种解决方案:从语法上来讲,promise是一个对象,从他可以获取异步操作的消息;从本意上来讲。他是一个承诺,承诺他过一段时间会给你一个结果。

他有三种状态:pending(等待态)、fulfiled(成功态)、rejected(失败态);状态一旦改变,就不会再变。

promise是用来解决两个问题的:

  • 回调地狱
  • 支持多个并发
  • promise可以解决异步的问题,本身不能说promise是异步的

2.如何实现Promise及Promise.resolve等方法

说到底,Promise还是使用回调函数,只不过是把回调封装在了内部,使用上一直通过then方法的链式调用,使得多层的回调嵌套看起来变成了同一层的。

//极简的实现
class Promise {
    callbacks = [];
    constructor(fn) {
        fn(this._resolve.bind(this));
    }
    then(onFulfilled) {
        this.callbacks.push(onFulfilled);
    }
    _resolve(value) {
        this.callbacks.forEach(fn => fn(value));
    }
}

//Promise应用
let p = new Promise(resolve => {
    setTimeout(() => {
        console.log('done');
        resolve('5秒');
    }, 5000);
}).then((tip) => {
    console.log(tip);
})

3.async/await如何实现的

首先Promise能很好地解决回调地狱的问题,但是这种方法充满了Promise的then方法,

如果处理复杂的的话,语义化不明显,执行流程不能很好表示。

于是ES7引入了async/await,

提供了在不阻塞主线程的情况下使用同步代码实现异步访问资源的能力,并且使得代码逻辑更加清晰

上来就讲怎么实现肯定听不懂,所以我们一步一步讲。

生成器如何工作

生成器函数是一个带星号函数,而且是可以暂停执行和恢复执行的

具体使用方式:

  1. 在生成器函数内部执行一段代码,如果遇到 yield 关键字,那么 JavaScript 引擎将返回关键字后面的内容给外部,并暂停该函数的执行。
  2. 外部函数可以通过 next 方法恢复函数的执行

函数为什么能停止和恢复呢?

了解一下协程,协程是一种比线程更加轻量级的存在,你可以把协程看成是跑在线程上的任务

  1. 通过调用生成器函数 genDemo 来创建一个协程 gen,创建之后,gen 协程并没有立即执行。
  2. 要让 gen 协程执行,需要通过调用 gen.next。
  3. 当协程正在执行的时候,可以通过 yield 关键字来暂停 gen 协程的执行,并返回主要信息给父协程。
  4. 如果协程在执行期间,遇到了 return 关键字,那么 JavaScript 引擎会结束当前协程,并将 return 后面的内容返回给父协程。

其实在 JavaScript 中,生成器就是协程的一种实现方式,利用下面的步骤

  • 首先执行的是let gen = foo(),创建了 gen 协程。然后在父协程中通过执行 gen.next 把主线程的控制权交给 gen 协程。
  • gen 协程获取到主线程的控制权后,就调用 fetch 函数创建了一个 Promise 对象 response1,然后通过 yield 暂停 gen 协程的执行,并将 response1 返回给父协程。
  • 父协程恢复执行后,调用 response1.then 方法等待请求结果。
  • 等通过 fetch 发起的请求完成之后,会调用 then 中的回调函数,then 中的回调函数拿到结果之后,通过调用 gen.next 放弃主线程的控制权,将控制权交 gen 协程继续执行下个请求。

把执行生成器的代码封装成一个函数,并把这个函数称为执行器。

虽然生成器已经满足我需求了,但是不够简洁,

其实 async/await 技术背后的秘密就是 Promise 和生成器应用,往低层说就是微任务和协程应用。

async

根据 MDN 定义,async 是一个通过异步执行隐式返回 Promise 作为结果的函数。

await

async function foo() {
    console.log(1)
    let a = await 100
    console.log(a)
    console.log(2)
}
console.log(0)
foo()
console.log(3)

执行到await 100时,会默认创建一个 Promise 对象,代码如下所示

let promise_ = new Promise((resolve,reject){
  resolve(100)
})

在这个 promise_ 对象创建的过程中,我们可以看到在 executor 函数中调用了 resolve 函数,JavaScript 引擎会将该任务提交给微任务队列。

因为 async/await 的基础技术使用了生成器和 Promise,生成器是协程的实现,利用生成器能实现生成器函数的暂停和恢复。

另外,V8 引擎还为 async/await 做了大量的语法层面包装

 

标签:协程,函数,生成器,Promise,执行,gen
From: https://www.cnblogs.com/alwaysrun/p/17178985.html

相关文章

  • 第125篇: 期约Promise基本特性
    好家伙,本篇为《JS高级程序设计》第十章“期约与异步函数”学习笔记 1.非重入期约1.1.可重入代码(百度百科)先来了解一个概念可重入代码(Reentrycode)也叫纯代码(Pure......
  • 关于Javascript——Promise的一些理解
    Promise是一个构造函数,promise是通过Promise构造函数声明的对象。 promise对象用来“管理”一次异步任务。 通过newPromise()声明一个promise对象的时候需要传两个参......
  • 第124篇: 期约Promise
    好家伙,本篇为《JS高级程序设计》第十章“期约与异步函数”学习笔记 1.异步编程同步行为和异步行为的对立统一是计算机科学的一个基本概念。特别是在JavaScript这种......
  • 使用npm包API Promise化
             ......
  • 我终于搞懂了async/await、promise和setTimeout的执行顺序
    从一道题目出发今天看到一道面试题,是关于async/await、promise和setTimeout的执行顺序,题目如下:asyncfunctionasync1(){console.log('async1start');awaitasync2(......
  • Promise的then方法
     调用then方法then方法返回结果是Promise对象,对象状态由回调函数的执行结果决定如果回调函数中返回的结果是非promise类型的属性,状态为成功,返回值为对象的成功then方法是......
  • 重学 MDN Web API 文档: Promise All In One
    重学MDNWebAPI文档:PromiseAllInOnePromiseconstmyPromise=newPromise((resolve,reject)=>{setTimeout(()=>{resolve("foo");},300);});......
  • 深入理解Promise
    Promise的前提概念Promise是一个构造函数,用来生成Promise实例Promise构造函数接受一个函数作为参数,该函数有两个参数,分别是resolve和rejectresolve:成功时的回调reject:......
  • Vue 中 Promise 的then方法异步使用及async/await 异步使用总结
    转载请注明出处:1.Promise的then方法使用then方法是 Promise中处理的是异步调用,异步调用是非阻塞式的,在调用的时候并不知道它什么时候结束,也就不会等到他返回......
  • [Javascript Tips] Use Promise.allSettled instead of Promise.all
    Promise.all: Problem:let'ssaywehavetwopromises,P1,P2,P1rejectin1s,andP2rejectin3s.Whatwillhappenincatchblock?ItonlyabletocatchP1......