Ajax使用以及Promise

这篇文章记录原生ajax的使用以及Promise

文章目录

  • 一、Ajax
    • 1、基本使用
    • 2、自己尝试封装一个ajax函数
  • 二、Promise
    • 1.Promise 创建
    • 2.基本使用
    • 2.对Ajax案例进行优化
  • 总结


提示:以下是本篇文章正文内容,下面案例可供参考

一、Ajax

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

1、基本使用

// 1创建XMLHttpRequest对象
    var xmlhttp
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest()
    } else { // 兼容早期浏览器
        xmlhttp = new ActiveXObject('Microsoft.XMLHTTP')
    }

    // 2发送请求
    xmlhttp.open('GET', url, true)
    xmlhttp.send()

    // 3服务端响应
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
            var obj = JSON.parse(xmlhttp.responseText)
            successCallback && successCallback(obj)
        } else if (xmlhttp.readyState === 4 && xmlhttp.status === 404) {
            failCallback && failCallback('Not Found')
        }
    }

2、自己尝试封装一个ajax函数

// Ajax原理
var url = 'xxxxxx'

function Ajax(url, callback) {
    // 1创建XMLHttpRequest对象
    var xmlhttp
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest()
    } else { // 兼容早期浏览器
        xmlhttp = new ActiveXObject('Microsoft.XMLHTTP')
    }

    // 2发送请求
    xmlhttp.open('GET', url, true)
    xmlhttp.send()


    // 3服务端响应
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
            var obj = JSON.parse(xmlhttp.responseText)
            callback(obj)
        }
    }
}


Ajax('url1', (res) => {
    console.log(res)
    Ajax('url2', (res) => {
        console.log(res)
        Ajax('url3', (res) => {
            console.log(res)
        })
    })
})

以上案例中最后的调用会产生回调地狱,这导致代码可读性非常低,下面可以使用Promise进行改造

二、Promise

ECMAscript 6 原生提供了 Promise 对象。
Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。
Promise 对象有以下两个特点:
1、对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:
pending: 初始状态,不是成功或失败状态。
fulfilled: 意味着操作成功完成。
rejected: 意味着操作失败。
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。
2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
Promise 优缺点
有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供统一的接口,使得控制异步操作更加容易。
Promise 也有一些缺点。首先,无法取消 Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。第三,当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

1.Promise 创建

要想创建一个 promise 对象、可以使用 new 来调用 Promise 的构造器来进行实例化。下面是创建 promise 的步骤:

var promise = new Promise(function(resolve, reject) {
    // 异步处理
    // 处理结束后、调用resolve 或 reject
});

2.基本使用

两个参数:
resolve 异步操作成功时调用
reject 异步操作不通过时调用
执行异步操作后调用
.then 异步操作完成后执行,接受两个函数作为参数,第一个是成功时执行,第二个是失败时执行
.catch 异步操作失败时在此捕获错误
.finally 无论结果如何,异步操作结束后都会执行

let promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log('imooc')
            // resolve('成功')
        reject('失败')
    }, 1000)
}).then((res) => {
    console.log(res)
}, (err) => {
    console.log(err)
})

可通过尝试以下案例查看输出结果具体了解Promise的使用

let p1 = new Promise((resolve, reject) => {
    resolve(1)
})
let p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(2)
    }, 1000)
})
let p3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(3)
    }, 1000)
})

console.log(p1)
console.log(p2)
console.log(p3)

setTimeout(() => {
    console.log(p2)
}, 2000)
setTimeout(() => {
    console.log(p3)
}, 2000)

p1.then((res) => {
    console.log(res)
}, (err) => {
    console.log(err)
})

p2.then((res) => {
    console.log(res)
}, (err) => {
    console.log(err)
})

p3.then((res) => {
    console.log(res)
}, (err) => {
    console.log(err)
})
p3.catch((err) => {
    console.log(err)
})

2.对Ajax案例进行优化

代码如下(示例):

// 改造Ajax异步状态
function Ajax(url, successCallback, failCallback) {
    // 1创建XMLHttpRequest对象
    var xmlhttp
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest()
    } else { // 兼容早期浏览器
        xmlhttp = new ActiveXObject('Microsoft.XMLHTTP')
    }

    // 2发送请求
    xmlhttp.open('GET', url, true)
    xmlhttp.send()

    // 3服务端响应
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
            var obj = JSON.parse(xmlhttp.responseText)
            successCallback && successCallback(obj)
        } else if (xmlhttp.readyState === 4 && xmlhttp.status === 404) {
            failCallback && failCallback('Not Found')
        }
    }
}

// 改造
function getPromise(url) {
    return new Promise((resolve, reject) => {
        Ajax(url, (res) => {
            resolve({ data: res, msg: '成功' })
        }, (err) => {
            reject({ err: err, data: '', msg: '失败' })
        })
    })
}

getPromise('url')
    .then((res) => {
        console.log(res)
        return getPromise('url1')
    }, (err) => {
        console.log(err)
        return getPromise('url1')
    }).then((res) => {
        console.log(res)
        return getPromise('url2')
    }, (err) => {
        console.log(err)
        return getPromise('url2')
    }).then((res) => {
        console.log(res)
    }).catch(err => {
        console.log(err)
    })

总结

一些注意事项
then、catch 和 finally 序列顺序颠倒,效果完全一样。但不建议这样做,最好按 then-catch-finally 的顺序编写程序。
除了 then 块以外,其它两种块能多次使用,finally 与 then 一样会按顺序执行,但是 catch 块只会执行第一个,除非 catch 块里有异常。所以最好只安排一个 catch 和 finally 块。
then 块默认会向下顺序执行,return 是不能中断的,可以通过 throw 来跳转至 catch 实现中断。
当需要多次顺序执行异步操作的时候,例如,如果想通过异步方法先后检测用户名和密码,需要先异步检测用户名,然后再异步检测密码的情况下就很适合 Promise。
Promise 不是一种将异步转换为同步的方法,Promise 只不过是一种更良好的编程风格。

这里只是学习Promise的一些基本使用,还有一些方法没有列出来,更多的教程建议查看: 菜鸟教程

你可能感兴趣的:(ajax,javascript,前端)