JS PromiseLike的判定与使用详解

 更新时间:2023年11月23日 14:55:44   作者:fengyehongWorld  
本文主要介绍了JS PromiseLike的判定与使用详解, 文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一. $.ajax()返回值遇到的问题

当我们执行如下js代码时,可以看到$.ajax()执行后,得到的response对象并不为空,并且response对象的responseJSON属性也确实是有值的。

但是,当我们执行response.responseJSON后,得到的居然是undefined
并且我们使用await 对response对象等待后,得到的就直接是response.responseJSON中的值。

setTimeout(async () => {

    const response = $.ajax({
        url: "https://api.github.com/users/fengyehong123",
        type: 'GET',
    });
    console.log(response);
    console.log(response.responseJSON);  // undefined

    const result = await response;
    console.log(result);

}, 1000);

执行效果如下:

在这里插入图片描述

上述现象是因为 $.ajax()得到的对象是一个 Promise Like对象,Promise Like对象和ES6的new Promise()一样,都是对 Promise A+ 规范的实现,因此可以使用 await 进行等待。

二. Promise A+ 规范

官网: https://promisesaplus.com/

ES6的new Promise()也好,$.ajax()函数返回的Promise Like对象也好,
都只是Promise A+规范的一种实现,该规范告诉我们如何自己实现一个Promise。

三. 判断是否为PromiseLike

如果一个值的类型为 object 或者 function并且 该值还存在一个then方法那么 该值就是一个 PromiseLike 对象。

// 判断是否为 Promise Like
 function isPromiseLike(value) {

    if(value === null) {
        return false;
    }
    
    if ((typeof value === 'object' || typeof value === 'function') && (typeof value.then === 'function')){
        return true;
    }

    return false;
}

3.1 判断ES6的new Promise()

ES6 的 new Promise() 是 Promise A+ 规范的实现,所以肯定是一个 PromiseLike 对象

const promise_obj = new Promise((resolve, reject) => {
    resolve('枫叶红');
});
console.log(isPromiseLike(promise_obj) ? "promise_obj是PromiseLike对象" : "promise_obj非PromiseLike对象");

3.2 判断包含then方法的对象

定义一个对象,对象里面有一个then方法,方法里面是耗时操作。符合该对象是一个Promise Like对象。

const then_response = {
    then: function(resolve, reject) {
        setTimeout(() => {
            resolve('贾飞天');
        }, 1000)
    }
}
console.log(
	isPromiseLike(then_response) 
	? "then_response是PromiseLike对象" : "then_response非PromiseLike对象"
);
// then_response是PromiseLike对象

(async (response) => {
    /*
        此处的response实际上是then_response
        因为 then_response 是一个 Promise Like 对象
        要想await的话,必须包裹在 函数中
        因此此处定义了一个立即执行函数,还可以避免给函数取名的麻烦
    */
    const result = await response;
    console.log(result);
})(then_response);

3.3 判断$.ajax()返回的对象

// ⏹两秒之后发送ajax请求
setTimeout(async () => {

    const response = $.ajax({
        url: "https://api.github.com/users/fengyehong123",
        type: 'GET',
    });
    
    // 是一个PromiseLike对象
    console.log(
		isPromiseLike(response) ? "response是PromiseLike对象" : "response非PromiseLike对象"
	);
    // response是PromiseLike对象

    // 正因为是 PromiseLike对象 ,所以才可以进行await
    const result = await response;
    console.log(result);
}, 2000);

也就是说,我们之后的$.ajax()函数可以这么写

// ajax的请求对象
const jqRequest = $.ajax({
    url,
    method: 'GET'
});

// doneCallBack,failCallBack,alwaysCallback 是从外部传入的回调函数
jqRequest.done(function(data, textStatus, jqXHR) {
    doneCallBack && doneCallBack(data);
}).fail(function(jqXHR, textStatus, errorThrown) {
    failCallBack && failCallBack();
}).always(function() {
    alwaysCallback && alwaysCallback();
});

也可以这么写,从而可以避免回调的方式

document.querySelector('#btn').addEventListener('click', async function() {

    const url = "https://api.github.com/users/fengyehong123";
    // 后端的返回值
    let result = null;

    try {
        result = await $.ajax({
            url,
            type: 'GET',
        });
    } catch (error) {

        const {responseJSON} = error;
        console.log(`请求失败!原因是: ${responseJSON}`);
    } finally {
        console.log("请求完成!");
    }

    if(!result) {
    	// 进行相应的业务处理
        return;
    }
   
    console.log("返回的最终值为:");
    console.log(result);
});

到此这篇关于JS PromiseLike的判定与使用详解的文章就介绍到这了,更多相关JS PromiseLike内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • new Date()问题在ie8下面的处理方法

    new Date()问题在ie8下面的处理方法

    本节主要介绍了ie8下面处理 new Date()的问题,需要的朋友可以参考下
    2014-07-07
  • webstorm中配置Eslint的两种方式及差异比较详解

    webstorm中配置Eslint的两种方式及差异比较详解

    这篇文章主要介绍了webstorm中配置Eslint的两种方式及差异比较详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • ExtJS实现文件下载的方法实例

    ExtJS实现文件下载的方法实例

    这篇文章介绍了ExtJS实现文件下载的方法实例,有需要的朋友可以参考一下
    2013-11-11
  • javascript实现相同事件名称,不同命名空间的调用方法

    javascript实现相同事件名称,不同命名空间的调用方法

    这篇文章主要介绍了javascript实现相同事件名称,不同命名空间的调用方法,涉及javascript命名空间及事件调用的技巧,需要的朋友可以参考下
    2015-06-06
  • JavaScript字符串常用类使用方法汇总

    JavaScript字符串常用类使用方法汇总

    今天的这篇文章就分享几年以来总结的一些最常见和最有用的字符串相关的方法的例子和简要说明。便于程序员用于快速参考。当然,最有经验的开发人员对这些操作很熟悉,但我认为这是一个很好的方法帮助初学者理解这些函数,他可以帮助你使用简单的语法,完成复杂的操作.
    2015-04-04
  • 在JavaScript中获取请求的URL参数[正则]

    在JavaScript中获取请求的URL参数[正则]

    在ASP.NET后台代码中,对于这样的URL请求地址:http://www.abc.com?id=001,我们可以通过Request.QueryString["id"]的方法很容易的获取到URL中请求的参数的值,但是要在前台js代码中获取请求的参数的值,应该怎么做呢?
    2010-12-12
  • 使用js获取地址栏参数的方法推荐(超级简单)

    使用js获取地址栏参数的方法推荐(超级简单)

    下面小编就为大家带来一篇使用js获取地址栏参数的方法推荐(超级简单)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • JavaScript实现文本目标字符替换和一键全部替换

    JavaScript实现文本目标字符替换和一键全部替换

    这篇文章主要介绍了JavaScript实现文本目标字符替换和一键全部替换,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-06-06
  • JavaScript 位运算及实际应用实例

    JavaScript 位运算及实际应用实例

    这篇文章主要为大家介绍了JavaScript位运算及实际应用实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • 前端大文件分片MinIO上传的详细代码

    前端大文件分片MinIO上传的详细代码

    这篇文章主要给大家介绍了关于前端大文件分片MinIO上传的详细代码,Minio支持分片上传大文件,这个功能可以让用户将大文件划分成小块,然后在多个并行的HTTP请求中上传这些小块,从而提高上传速度和稳定性,需要的朋友可以参考下
    2024-09-09

最新评论