es6--promise

目录

一、初识promise

 1.1  什么是promise

1.2  Promise对象的特点

1.3  Promise的缺点

1.4  promise的基本用法

1.5  then 方法

1.6  resolve 和 reject 函数的参数

二、promise的实例方法

2.1  then()方法

2.1.1 什么时候执行

2.1.2  执行后的返回值

2.1.3  then 方法返回的 Promise 对象的状态改变

2.2   catch()方法 

2.2.1  catch()特点

2.2.2  基本用法

2.3  finally()方法(了解)

2.3.1  什么时候执行

2.3.2  本质

三、promise的构造函数方法

3.1  promise.resolve()方法和promise.reject()方法

3.1.1  Promise.resolve()

3.1.2  Promise.reject()

3.2  promise.all()方法

 a.有什么用

 b.基本用法

c.特点

3.3  promise.race()方法

3.4  promise.allSettled()方法

3.4.1 特点

3.4.2 应用场景

四、promise的注意事项和应用

4.1  promise的注意事项

4.1.1   resolve 或 reject 函数执行后的代码

4.1.2  Promise.all/race/allSettled 的参数问题

4.1.3 Promise.all/race/allSettled 的错误处理

4.2  promise的应用

4.2.1  异步加载图片

4.2.2 按需加载

4.3  promise 改造Ajax


一、初识promise

 1.1  什么是promise

  • 异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大
  • promise一般是用来解决层层嵌套的回调函数的问题(回调地狱)
  • 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果
  • 从语法上说,Promise 是一个对象,从它可以获取异步操作的消息
  • 提供统一的 API,各种异步操作都可以用同样的方法进行处理

示例:回调地狱(了解)

 <div id="box"></div>
<style>
        * {
            padding: 0;
            margin: 0;
        }
        
        #box {
            width: 300px;
            height: 300px;
            background-color: red;
            transition: all 0.5s;
        }
    </style>
<script>
        const move = (el, {
            x = 0,
            y = 0
        } = {}, end = () => {}) => {
            el.style.transform = `translate3d(${x}px, ${y}px, 0)`;

            el.addEventListener(
                'transitionend',
                () => {
                    // console.log('end');
                    end();
                },
                false
            );
        };
        const boxEl = document.getElementById('box');

        document.addEventListener(
            'click',
            () => {
                move(boxEl, {
                    x: 150
                }, () => {
                    move(boxEl, {
                        x: 150,
                        y: 150
                    }, () => {
                        move(boxEl, {
                            y: 150
                        }, () => {
                            // console.log('object');
                            move(boxEl, {
                                x: 0,
                                y: 0
                            });
                        });
                    });
                });
            },
            false
        );
</script>


1.2  Promise对象的特点

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果


1.3  Promise的缺点

  1. 无法取消Promise,一旦新建它就会立即执行,无法中途取消
  2. 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
  3. 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

如果某些事件不断地反复发生,一般来说,使用 Stream 模式是比部署Promise更好的选择


1.4  promise的基本用法

  •  实例化构造函数生成实例对象
  • promise的3种状态
  • then()方法
  • resolve()和reject()函数的参数

promise对象本身不是异步的,只要创建了promise对象就会立即执行存放的代码

 a.实例化构造函数生成实例对象:

​console.log(Promise);

//Promise 解决的不是回调函数,而是回调地狱

const p = new Promise(() => {

function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }

[点击并拖拽以移动]

});
​

解释:

  • Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署
  • resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

b.Promise 的状态:

 const p = new Promise((resolve, reject) => {

            // Promise 有 3 种状态,

            //一开始是 pending(未完成),执行 resolve,变成 fulfilled(resolved),已成功

            // 执行 reject,变成 rejected,已失败

            // Promise 的状态一旦变化,就不会再改变了

            // pending->fulfilled

            resolve(); //这里由于resolve()在前面,因此在此时状态就是fulfilled,就不会再改变,即使下面还会再执行reject(0

            // pending->rejected

            reject();

        });
console.log(p);


1.5  then 方法

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数,即then方法接收两个参数:

第一个参数是状态切换成功时的回调

第二个参数是切换失败时的回调

示例:

 const p = new Promise((resolve, reject) => {

            resolve(); // 将状态切换为成功

            // reject(); //将状态切换为失败
        });
        console.log(p);
        p.then(

            () => { // 成功时执行
                console.log('success');
            },

            () => { // 失败时执行
                console.log('error');
            }

        );


1.6  resolve 和 reject 函数的参数

在修改promise状态时,可以传递参数给then()中的回调函数

const p = new Promise((resolve, reject) => {

            // pending->fulfilled
            // resolve('succ');
            resolve({
                username: 'alex'
            });

            // pending->rejected
            // reject('reason');
            // reject(new Error('reason'));
        });
        p.then(
            data => {
                console.log('success', data);
            },
            err => {
                console.log('error', err);
            }
        );

        console.log(p);

 注意:其状态只能是pending(未完成)->fulfilled成功()或者pending(未完成)->rejected(失败)


二、promise的实例方法

2.1  then()方法

2.1.1 什么时候执行

 pending->fulfilled 时,执行 then 的第一个回调函数

pending->rejected 时,执行 then 的第二个回调函数


2.1.2  执行后的返回值

同一个promise对象可以多次调用then(),当该promise对象的状态改变时所有then()都会执行

then 方法执行后返回一个新的 Promise 对象

//then 方法执行后返回一个新的 Promise 对象
const p = new Promise((resolve, reject) => {
            resolve();
            //reject();
        });

        const p2 = p
            .then(
                () => {},//成功后执行
                () => {} //失败后执行
            )

        .then()
            .then();

        console.log(p, p2, p === p2);


2.1.3  then 方法返回的 Promise 对象的状态改变

同一个promise对象可以多次调用then(),当该promise对象的状态改变时所有then()都会执行  

then 方法每次执行完后都会返回一个新的 Promise 对象

可以通过上一个promise对象的then()给下一个promise对象的then()传递参数,需要注意的是无论是在上一个promise对象成功的回调还是失败的回调传递的参数,都会传递给下一个promise对象成功的回调

//then 方法执行后返回一个新的 Promise 对象  
const p = new Promise((resolve, reject) => {
            // resolve();
            reject();
        });

        p.then(
            () => { //成功之后执行的
                console.log('success');
            },
            () => { //失败之后执行的
                console.log('err');

                 //利用return进行给下一个promise对象的then()传参
                //在then()的回调函数中,return后面的东西,会自动用Promise包装一下

                //return undefined;
                // 等价于
                // return new Promise((resolve, reject) => {
                //     resolve(123);
                // });

                //默认返回的永远都是成功状态的Promise对象

                //若想返回失败则:
                return new Promise((resolve, reject) => {
                    reject('reason');
                });
            }
        ).then((data) => {
        // 前一个then()执行后,返回的心的promise对象才能决定后一个promise对象
            console.log('success2', data);
        }, (err) => {
            console.log('error2');
        }).then((data) => {
        //由于默认返回的永远都是成功状态的Promise对象,因此在这里会执行data,而不是err,
        //要想执行err,就必须向上面那样进行修改
            console.log('success3', data);
        }, ((err) => {
            console.log('err3', err);
        }));


2.2   catch()方法 

catch()其实是then()的语法糖

  1.  catch 专门用来处理 rejected 状态
  2. catch 本质上是 then 的特例
  3.  catch() 可以捕获它前面的错误
  4. 一般总是建议,Promise 对象后面要跟 catch 方法,这样可以处理 Promise 内部发生的错误

2.2.1  catch()特点

  • 和then()一样,在修改promise状态时,可以传递参数给catch()中的回调函数
        let p = new Promise((resolve, reject) => {
            reject('123');
        });
        p.catch(data => {
            console.log(data); //123
        })
  • 和then()一样,同一个promise对象可以多次调用catch(),当该promise对象的状态发生改变时所有catch()都会执行
        let p = new Promise((resolve, reject) => {
            reject();
        });
        p.catch(() => {
            console.log('失败1'); //
        })
        p.catch(() => {
            console.log('失败2'); //
        })
        p.catch(() => {
            console.log('失败3'); //
        })

  • 和then()一样,catch()每次执行完毕后会返回一个新的promise对象
        let p = new Promise((resolve, reject) => {
            reject();
        });
        let p1 = p.catch(() => {
            console.log('失败1'); //
        });
        console.log(p === p1); //false
  • 和then()一样,上一个promise对象也可以给下一个promise成功的传递参数,需要注意的是无论是在上一个promise对象成功的回调还是失败的回调传递的参数,都会传递给下一个promise对象成功的回调
        let p = new Promise((resolve, reject) => {
            reject();
        });
        let p1 = p.catch(() => {
            console.log('失败1'); //
            return '789';
        });
        p1.then((data) => {
            console.log('成功2');
        }, (data) => {
            console.log('失败2');
        });

  • 和then()一样,catch()如果返回的是一个promise对象,那么会将返回的promise对象的执行结果中的值传递给下一个catch()

        let p = new Promise((resolve, reject) => {
            reject();
        });

        let pp = new Promise((resolve, reject) => {
            resolve('111');
            // reject('abc');
        });

        let p1 = p.catch(() => {
            console.log('失败1'); //
            return pp;
        });

        p1.then((data) => {
            console.log('成功2');
        }, (data) => {
            console.log('失败2');
        });

  •  和then()第二个参数的区别在于,catch()可以捕获上一个promise对象then()中的异常
        let p = new Promise((resolve, reject) => {
            resolve();
        });

        p.then(() => {
            console.log('成功');
            xxx
        }).catch((e) => {
            console.log('失败', e);
        });


2.2.2  基本用法

 <script>
        new Promise((resolve, reject) => {
                // resolve(123);
                reject('reason');
            })
            .then(data => {
                console.log(data);
            })
            // .then(null, err => {
            //   console.log(err);
            // });
            .catch(err => {
                console.log(err);

                // return undefined;默认情况下总是执行resolve(),返回成功状态的

                throw new Error('reason'); //直接抛出错误,改变状态
            })
            .then(data => {
                console.log(data);
            })
            .catch(err => {
                console.log(err);
            });
    </script>


2.3  finally()方法(了解)

2.3.1  什么时候执行

当 Promise 状态发生变化时,不论如何变化都会执行,不变化不执行

 new Promise((resolve, reject) => {
                // resolve(123);
                reject('reason');
            })
            .finally(data => {
                console.log(data);
            })
            .catch(err => {});

2.3.2  本质

 finally() 本质上是 then() 的特例

  // new Promise((resolve, reject) => {
        //         // resolve(123);
        //         reject('reason');
        //     })
        //     .finally(data => {
        //         console.log(data);
        //     })
        //     .catch(err => {});

        // 等同于
        new Promise((resolve, reject) => {
                // resolve(123);
                reject('reason');
            })
            .then(
                result => {
                    return result;
                },
                err => {
                    return new Promise((resolve, reject) => {
                        reject(err);
                    });
                }
            )
            .then(data => {
                console.log(data);
            })
            .catch(err => {
                console.log(err);
            });


三、promise的构造函数方法

3.1  promise.resolve()方法和promise.reject()方法

3.1.1  Promise.resolve()

是成功状态 Promise 的一种简写形式

new Promise(resolve => resolve('foo'));

简写

Promise.resolve('foo');

参数:

一般参数:

       

 <script>
        Promise.resolve('foo').then(data => {

            console.log(data);

        });
    </script>

 特殊参数:

1.Promise

当 Promise.resolve() 接收的是 Promise 对象时,直接返回这个 Promise 对象,什么都不做

<script>
        const p1 = new Promise(resolve => {
            setTimeout(resolve, 1000, '我执行了');
            // setTimeout(() => {
            //   resolve('我执行了');
            // }, 1000);
        });

        Promise.resolve(p1).then(data => {
            console.log(data);
        });

        // 等价于
        p1.then(data => {
            console.log(data);
        });
        console.log(Promise.resolve(p1) === p1);
</script>

   

当 resolve 函数接收的是 Promise 对象时,后面的 then 会根据传递的 Promise 对象的状态变化决定执行哪一个回调

 <script>
        const p1 = new Promise(resolve => {
            setTimeout(resolve, 1000, '我执行了');
            // setTimeout(() => {
            //   resolve('我执行了');
            // }, 1000);
        });

        new Promise(resolve => resolve(p1)).then(data => {
            console.log(data);
        });
    </script>

2.具有 then 方法的对象

 <script>
        const thenable = {
            then(resolve, reject) {
                console.log('then');
                resolve('data');
                // reject('reason');
            }
        };

        Promise.resolve(thenable).then(
            data => console.log(data),
            err => console.log(err)
        );

        console.log(Promise.resolve(thenable));
</script>


3.1.2  Promise.reject()

  失败状态 Promise 的一种简写形式

        new Promise((resolve, reject) => {

          reject('reason');

        });

        等价于

        Promise.reject('reason');

参数

     不管什么参数,都会原封不动地向后传递,作为后续方法的参数

 <script>
        const p1 = new Promise(resolve => {
            setTimeout(resolve, 1000, '我执行了');
        });
        Promise.reject(p1).catch(err => console.log(err));
    </script>

示例2:

<script>
        new Promise((resolve, rejcet) => {
                resolve(123);
            })
            .then(data => {
                // return data;

                // return Promise.resolve(data);

                return Promise.reject('reason');
            })
            .then(data => {
                console.log(data);
            })
            .catch(err => console.log(err));
</script>


3.2  promise.all()方法

 a.有什么用

  • Promise.all() 关注多个 Promise 对象的状态变化
  • 传入多个 Promise 实例,包装成一个新的 Promise 实例返回

 b.基本用法

  •  Promise.all() 的状态变化与所有传入的 Promise 实例对象状态有关
  • 所有状态都变成 resolved,最终的状态才会变成 resolved
  • 只要有一个变成 rejected,最终的状态就变成 rejected

c.特点

会返回一个新的promise对象

会按照传入数组的顺序将所有promise中成功返回的结果保存到一个新的数组中返回

数组中有一个promise失败就会失败,只有所有成功才会成功

<script>
        const delay = ms => {
            return new Promise(resolve => {
                setTimeout(resolve, ms);
            });
        };

        const p1 = delay(1000).then(() => {
            console.log('p1 完成了');

            // return 'p1';
            return Promise.reject('reason');
        });

        const p2 = delay(2000).then(() => {
            console.log('p2 完成了');

            return 'p2';
            // return Promise.reject('reason');
        });


        const p = Promise.all([p1, p2]);

        p.then(
            data => {
                console.log(data);
            },
            err => {
                console.log(err);
            }
        );
</script>


3.3  promise.race()方法

Promise.race() 的状态取决于第一个完成的 Promise 实例对象,如果第一个完成的成功了,那最终的就成功;如果第一个完成的失败了,那最终的就失败

<script>
        const delay = ms => {
            return new Promise(resolve => {
                setTimeout(resolve, ms);
            });
        };
        const p1 = delay(1000).then(() => {
            console.log('p1 完成了');

            return 'p1';
            // return Promise.reject('reason');
        });
        const p2 = delay(2000).then(() => {
            console.log('p2 完成了');

            // return 'p2';
            return Promise.reject('reason');
        });

        const racePromise = Promise.race([p1, p2]);
        racePromise.then(
            data => {
                console.log(data);
            },
            err => {
                console.log(err);
            }
        );
</script>


3.4  promise.allSettled()方法

 Promise.allSettled() 的状态与传入的Promise 状态无关

永远都是成功的

它只会忠实的记录下各个 Promise 的表现

3.4.1 特点

接收一个数组

如果数组中有多个promise对象,谁先返回状态就听谁的,后返回的就会被抛弃

如果数组中不是promise对象,那么会直接执行then()

 <script>
        const delay = ms => {
            return new Promise(resolve => {
                setTimeout(resolve, ms);
            });
        };
        const p1 = delay(1000).then(() => {
            console.log('p1 完成了');

            return 'p1';
            // return Promise.reject('reason');
        });
        const p2 = delay(2000).then(() => {
            console.log('p2 完成了');

            // return 'p2';
            return Promise.reject('reason');
        });

        const allSettledPromise = Promise.allSettled([p1, p2]);

        allSettledPromise.then(data => {
            console.log('succ', data);
        });
</script>

 

3.4.2 应用场景

接口调试、超时处理

        let url = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2Ftp01%2F1ZZQ20QJS6-0-lp.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639382820&t=005df0df320dfe0d7a43cfa605b65bca";

        function loadImg(url) {
            return new Promise((resolve, reject) => {
                //设置图片地址 
                let oImg = new Image();
                setTimeout(function() {
                    oImg.src = url;
                }, 5000);

                //图片加载成功
                oImg.onload = () => {
                    resolve(oImg);
                };

                //图片加载失败
                oImg.onerror = () => {
                    reject("图片加载失败");
                };
            });
        }

        function timeOut() {
            return new Promise((resolve, reject) => {
                setTimeout(function() {
                    reject("超时了");
                }, 3000)
            });
        }

        Promise.race([loadImg(url), timeOut()]).then((value) => {
            console.log("成功", value);
        }).catch(error => {
            console.log("失败", error);
        });

 


四、promise的注意事项和应用

4.1  promise的注意事项

4.1.1   resolve 或 reject 函数执行后的代码

推荐在调用 resolve 或 reject 函数的时候加上 return,不再执行它们后面的代码

<script>
        new Promise((resolve, reject) => {
            // return resolve(123);
            return reject('reason');

            console.log('hi');
        });
    </script>


4.1.2  Promise.all/race/allSettled 的参数问题

参数如果不是 Promise 数组,会将不是 Promise 的数组元素转变成 Promise 对象

 <script>
        Promise.all([1, 2, 3]).then(datas => {
            console.log(datas);
        });

        //等价于
        Promise.all([
            Promise.resolve(1),
            Promise.resolve(2),
            Promise.resolve(3)
        ]).then(datas => {
            console.log(datas);
        });
    </script>

不只是数组,任何可遍历的都可以作为参数:数组、字符串、Set、Map、NodeList、arguments

<script>
        Promise.all(new Set([1, 2, 3])).then(datas => {
            console.log(datas);
        });
    </script>


4.1.3 Promise.all/race/allSettled 的错误处理

错误既可以单独处理,也可以统一处理

一旦被处理,就不会在其他地方再处理一遍

<script>
        const delay = ms => {
            return new Promise(resolve => {
                setTimeout(resolve, ms);
            });
        };

        const p1 = delay(1000).then(() => {
            console.log('p1 完成了');

            // return 'p1';
            return Promise.reject('reason');
        });

        //方式1:单独处理
        // .catch(err => {
        //   console.log('p1', err);
        // });

        const p2 = delay(2000).then(() => {
            console.log('p2 完成了');

            return 'p2';
            // return Promise.reject('reason');
        });

        //方式1:单独处理
        // // .catch(err => {
        // //   console.log('p2', err);
        // });

        const allPromise = Promise.all([p1, p2]);

        //方式2:统一处理
        allPromise
            .then(datas => {
                console.log(datas);
            })
            .catch(err => console.log(err));
    </script>


4.2  promise的应用

4.2.1  异步加载图片

 <style>
        #img {
            width: 80%;
            padding: 10%;
        }
    </style>
<img src="https://img.mukewang.com/5e6af63d00011da318720764.jpg" alt="" id="img" />
<script>
        // 异步加载图片
        const loadImgAsync = url => {
            return new Promise((resolve, reject) => {
                const img = new Image();

                img.onload = () => {
                    resolve(img);
                };

                img.onerror = () => {
                    reject(new Error(`Could not load image at ${url}`));
                };

                img.src = url;
            });
        };

        const imgDOM = document.getElementById('img');

        loadImgAsync('https://2img.mukewang.com/5f057a6a0001f4f918720764.jpg')
            .then(img => {
                console.log(img.src);
                setTimeout(() => {
                    imgDOM.src = img.src;
                }, 1000);
            })
            .catch(err => {
                console.log(err);
            });
    </script>

4.2.2 按需加载

只要前一张图片未成功加载,后面的图片就不会加载

        img {
            width: 500px;
            height: 200px;
        }
        let arr = [
            'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2Ftp01%2F1ZZQ20QJS6-0-lp.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639382820&t=005df0df320dfe0d7a43cfa605b65bca',
            'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Ffile02.16sucai.com%2Fd%2Ffile%2F2014%2F0427%2F071875652097059bbbffe106f9ce3a93.jpg&refer=http%3A%2F%2Ffile02.16sucai.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639382866&t=be9a0d43f75a116ba82d76cefc39da13',
            'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2Fedpic_source%2F53%2F0a%2Fda%2F530adad966630fce548cd408237ff200.jpg&refer=http%3A%2F%2Fup.enterdesk.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639382866&t=0ae45b7d5b66fdbe3d63310edd0af1aa'
        ];

        function loadImg(url) {
            return new Promise((resolve, reject) => {
                //设置图片地址 
                let oImg = new Image();
                oImg.src = url;

                //图片加载成功
                oImg.onload = () => {
                    resolve(oImg);
                };

                //图片加载失败
                oImg.onerror = () => {
                    reject("图片加载失败");
                };
            });
        }

        let p = loadImg(arr[0]).then((oImg) => {
            // console.log(oImg);
            //将加载成功的图片加载到页面
            document.body.appendChild(oImg);
            return loadImg(arr[1]);
        }).then((oImg) => {
            // console.log(oImg);
            //将加载成功的图片加载到页面
            document.body.appendChild(oImg);
            return loadImg(arr[2]);
        }).then((oImg) => {
            // console.log(oImg);
            //将加载成功的图片加载到页面
            document.body.appendChild(oImg);
        }).catch((msg) => {
            console.log(msg);
        });

 这时如果故意将第二张的图片地址弄错,则会:

 


4.3  promise 改造Ajax

    <script>
        function objTostr(data) {
            data = data || {};
            data.t = new Date().getTime();
            var res = [];
            for (var key in data) {
                res.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
            }
            return res.join("&");
        }

        function ajax(option) {
            return new Promise(function(resolve, reject) {
                // 0.将对象转换为字符串
                var str = objTostr(option.data);
                // 1.创建一个异步对象
                var xmlhttp, timer;
                if (window.XMLHttpRequest) {
                    xmlhttp = new XMLHttpRequest();
                } else {
                    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                }
                // 2.设置请求方式和请求地址
                if (option.type.toLowerCase() === "get") {
                    xmlhttp.open(option.type, option.url + "?" + str, true);
                    // 3.发送请求
                    xmlhttp.send();
                } else {
                    xmlhttp.open(option.type, option.url, true);
                    // 注意点: 以下代码必须放到open和send之间
                    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                    xmlhttp.send(str);
                }

                // 4.监听状态的变化
                xmlhttp.onreadystatechange = function(ev2) {
                        if (xmlhttp.readyState === 4) {
                            clearInterval(timer);
                            // 判断是否请求成功
                            if (xmlhttp.status >= 200 && xmlhttp.status < 300 ||
                                xmlhttp.status === 304) {
                                // 5.处理返回的结果
                                // console.log("接收到服务器返回的数据");
                                // option.success(xmlhttp);
                                resolve(xmlhttp);
                            } else {
                                // console.log("没有接收到服务器返回的数据");
                                // option.error(xmlhttp);
                                reject(xmlhttp);
                            }
                        }
                    }
                    // 判断外界是否传入了超时时间
                if (option.timeout) {
                    timer = setInterval(function() {
                        console.log("中断请求");
                        xmlhttp.abort();
                        clearInterval(timer);
                    }, option.timeout);
                }
            });
        }
    </script>
    <script>
        ajax({
            type: "post",
            url: "40.php",
            // success: function (xhr) {
            //     let str = xhr.responseText;
            //     let json = JSON.parse(str);
            //     console.log(json);
            // },
            // error: function (xhr) {
            //     console.log(xhr.status);
            // }
        }).then(function(xhr) {
            let str = xhr.responseText;
            let json = JSON.parse(str);
            console.log(json);
        }).catch(function(xhr) {
            console.log(xhr.status);
        });
    </script>

40.php,

<?php
$arr = array("name"=>"lwj", "age"=>"2");
$data = json_encode($arr);
echo $data;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白小白从不日白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值