最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JavaScript 中 你需要知道的 Promise 详细知识点

    正文概述 掘金(日升)   2021-05-13   524

    JavaScript 中 你需要知道的 Promise 详细知识点

    1、如何实现一个 sleep 函数(延迟函数)

    通过 promisesetTimeout 来简单实现

    /**
     * 延迟函数
     * @param {Number} time 时间
     */
    function sleep (time = 1500) {
        return new Promise((resolve) => {
            setTimeout(() => {
                resolve(true)
            }, time)
        })
    }
    

    2、promise 构造函数、then 方法、catch 方法、finally 方法哪个异步哪个同步?

    promise 构造函数是同步执行的,thencatchfinally 方法是异步执行的。

    3、如何取消一个 promise

    取消一个promise

    1. 使用 promise.race()

    • Promise.race(iterable)

    iterable 参数里的任意一个子 promise 被成功或失败后,父 promise 马上也会用子 promise 的成功返回值或失败详情作为参数调用父 promise 绑定的相应句柄,并返回该 promise 对象。

    /**
    * @author guoqiankunmiss
    */
    //封装一个取消promise的函数,使用promise.race的特性
    function stopPromise (stopP) {
    	let proObj = {};
    	let promise = new Promise((resolve, reject) => {
    		proObj.resolve = resolve;
    		proObj.reject = reject;
    	})
    	proObj.promise = Promise.race([stopP, promise])
    	return proObj
    }
    //一个5秒钟之后执行的.then方法的promise
    let promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(123);
        }, 5000);
    });
    //调用函数
    let obj = stopPromise(promise);
    //收集返回值
    obj.promise.then(res => {
        console.log(res);
    });
    //两秒钟之后进行取消promise操作
    setTimeout(() => {
    	obj.resolve("Promise 请求被取消了!");
    }, 2000)
    

    4、多个 promise 如何获取第一个成功promise

    多个Promise中获取第一个成功的Promise

    1. Promise.all 改进

    利用 promise.all 的特性,遍历 promise 数组,根据返回值进行判断,当成功的时候,转为 reject 返回,当失败的时候转为 resolve 继续执行。

    //第一个成功的Promise
    function firstProSuccess (allProMise) {
      //遍历promise数组,根据返回值进行判断,当成功的时候,转为reject返回,当失败的时候转为resolve继续执行。
      return Promise.all(allProMise.map(item => {
        return item.then(
          res => Promise.reject(res),
          err => Promise.resolve(err)
        )
      })).then(
        errors => Promise.reject(errors),
        val => Promise.resolve(val)
      )
    }
    

    2. Promise.any

    • Promise.any(iterable)

    接收一个 Promise 对象的集合,当其中的一个 promise 成功,就返回那个成功的 promise 的值。

    缺点:有兼容问题

    5、多个 promise,所有的 promise 都取得返回结果(不管成功/失败都要返回值)

    1. Promise.all 改进

    和上面原理类似,只不过是当成功的时候不进行操作,当 reject 时进行 resolve 操作

    2. Promise.allSettled()

    • Promise.allSettled(iterable)

    返回一个在所有给定的 promise 都已经 fulfilledrejected 后的 promise

    缺点:有兼容问题

    6、说说 promise 的静态方法有哪些?

    1. Promise.all(iterable)

    接收一个 promise 数组对象(可迭代的 promise 实例对象),全部成功时,返回所有 promise 的数组集合;当其中一个失败时,返回当前失败的 promise 对象。

    2. Promise.allSettled(iterable)

    接收一个 promise 数组对象,全部完成时(不管成功/失败)返回新的 promise 数组集合

    3. Promise.any(iterable)

    接收一个 promise 数组对象,当其中任何一个成功时,返回成功的 promise

    4. Promise.race(iterable)

    接收一个 promise 数组对象,当其中任意一个成功/失败时,返回该 promise

    5. Promise.reject(reason)

    返回一个状态为失败的 Promise 对象。

    6. Promise.resolve(value)

    返回一个状态由给定 value 决定的 Promise 对象。

    7. Promise.finally(onFinally)

    在当前 promise 运行完毕后被调用,无论当前 promise 的状态是完成( fulfilled )还是失败( rejected )

    8. Promise.try(f)

    接收一个函数,返回一个 promise

    为所有操作提供了统一的处理机制,所以如果想用 then 方法管理流程,最好都用 Promise.try 包装一下。

    • 更好的错误处理
    • 更好的互操作性
    • 易于浏览

    Promise-try

    7、Promise.then 的第二个参数有了解吗?和 .catch 有什么区别?

    then() 方法返回一个 Promise

    它最多需要有两个参数Promise 的成功和失败情况的回调函数。

    p.then(onFulfilled[, onRejected]);
    p.then(value => {
      // fulfillment
    }, reason => {
      // rejection
    });
    

    第二个参数也是一个函数,是对失败情况的回调函数。

    then 第二个参数catch
    then 方法的参数Promise 的实例方法then 的第一个参数抛出异常捕获不到then 的第一个参数抛出异常可以捕获是一个函数本质是 then 方法的语法糖如果第二个参数和 catch 同时存在,promise 内部报错,第二个参数可以捕获此时,catch 捕获不到,第二个参数不存在,catch 才会捕获到不建议使用建议使用 catch 进行错误捕获

    8、Promise.resolve 有几种情况?

    1. 参数是一个 Promise 实例

    参数是 Promise 实例,那么 Promise.resolve 将不做任何修改、原封不动地返回这个实例。

    2. 参数是一个 thenable 对象

    Promise.resolve() 方法会将这个对象转为 Promise 对象,然后就立即执行 thenable 对象的 then() 方法。

    3. 参数不是具有 then() 方法的对象,或根本就不是对象

    如果参数是一个原始值,或者是一个不具有 then() 方法的对象,则 Promise.resolve() 方法返回一个新的 Promise 对象,状态为 resolved

    4. 不带有任何参数

    直接返回一个 resolved 状态的 Promise 对象。

    9、如果 .then 中的参数不是函数,那会怎样?

    Promise.resolve(1)
        .then(2)
        .then(console.log)
    // 1
    

    如果 .then 中的参数不是函数,则会在内部被替换为 (x) => x,即原样返回 promise 最终结果的函数。

    10、如果 .finally 后面继续跟了个 .then,那么这个 then 里面的值是什么?

    Promise.resolve('resolve')
      .finally(() => {
        console.log('this is finally')
        return 'finally value'
      })
      .then(res => {
        console.log('finally后面的then函数, res的值为:', res)
      })
    // this is finally
    

    finally 后面的 then 函数, res 的值为: resolve

    1. finally 的回调函数中不接收任何参数;
    2. promise 结束时,无论结果是 fulfilled 或者是 rejected,都会执行 finally 回调函数;
    3. finally 返回的是一个上一次的 Promise 对象值。

    11、.all.race 在传入的数组有第一个抛出异常的时候,其他异步任务还会继续执行吗?

    会的,会继续执行,只是不会在 then / catch 中表现出来。

    浏览器执行下面代码,可以看出当报错的时候 console 还是会继续执行的,只是在 对应的回调函数里面没有表现出来。

    function sleep (n) {
        return new Promise((resolve, reject) => {
            console.log(n)
            Math.random() > 0.5 ? reject(n) : resolve(n)
        }, n % 2 === 0 ? 1000 * n : 1000)
    }
    Promise.all([sleep(1), sleep(2), sleep(3)])
      .then(res => console.log('all res: ', res))
      .catch(err => console.log('all err:', err))
    Promise.race([sleep(1), sleep(2), sleep(3)])
      .then(res => console.log('race res: ', res))
      .catch(err => console.log('race err:', err))
    

    12、.all 是并发的还是串行的?

    是并发的,但是返回值和 promise.all 中接收到的数组顺序一样。

    13、promise 为什么可以进行链式调用

    因为 thencatchfinally 方法会返回一个新的 promise,所以允许我们进行链式调用。

    14、async/await

    1. 实现原理

    async 函数是基于 generator 实现,所以涉及到 generator 相关知识。 在没有async 函数之前,通常使用 co 库来执行 generator,所以通过 co 我们也能模拟 async 的实现。

    2. 简单实现

    1)co
    function Asyncfn() {
      return co(function*() {
        //.....
      });
    }
    function co(gen) {
      return new Promise((resolve, reject) => {
        const fn = gen();
        function next(data) {
          let { value, done } = fn.next(data);
          if (done) return resolve(value);
          Promise.resolve(value).then(res => {
            next(res);
          }, reject);
        }
        next();
      });
    }
    
    2)Generator 函数和自执行器
    function spawn(genF) {
        return new Promise(function(resolve, reject) {
            const gen = genF();
            function step(nextF) {
                let next;
                try {
                    next = nextF();
                } catch (e) {
                    return reject(e);
                }
                if (next.done) {
                    return resolve(next.value);
                }
                Promise.resolve(next.value).then(
                    function(v) {
                        step(function() {
                            return gen.next(v);
                        });
                    },
                    function(e) {
                        step(function() {
                            return gen.throw(e);
                        });
                    }
                );
            }
            step(function() {
                return gen.next(undefined);
            });
        });
    }
    

    起源地下载网 » JavaScript 中 你需要知道的 Promise 详细知识点

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元