美文网首页
JS Promise的应用

JS Promise的应用

作者: 与时间赛跑_ | 来源:发表于2019-06-21 00:20 被阅读0次

    Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。

    简单理解:

    Promise顾名思义就是一个承诺,如果承诺兑现了,就做计划好的下一件事,如果没兑现就不继续做下一件事。(Romance in the code world)

    Promise的几种状态

    首先这种状态不收外界干扰,Proimse对象代表了一个异步操作。

    状态1: pending  (进行中)

    状态2:fulfilled   (已成功)

    状态3:rejected(已失败)

    改变promise的状态的方式只有一个,那就是异步的结果。promise对象一旦状态改变,就不会再变,任何时候都可以得到这个结果,它们相互转变的方式如下:

    pending=>fulfilled

    pending=>rejected

    这两种状态一旦发生就无法再改变了,成为定性(resolved)。

    文艺的话说就是,一旦错过,就再也无法挽回。请好好珍惜。哈哈哈。

    简单的例子:

    class POP {

    toAn(data) {

    return new Promise((resolve,reject)=>{

    resolve();//第一遍

    resolve();//第二遍

    });

    }

    test(){

    this.toAn({}).then(this.toK.bind(null,100));

    }

    toK(res){

    console.log(res);

    }

    }

    let pop=new POP();

    pop.test();

    你将看到如下输出(是的,只有一个):

    100

    Promise无法被取消

    promise最大的缺点就是一旦创建就无法被取消,并且,如果未设置回调函数,它就会在内部抛出错误,但这种错误无法反应到外部,所以你不得而知。你甚至无法知道现在promise事件处理到哪个阶段,处理得怎么样了。resolve和reject函数的作用,resolve的作用是:pending=>resoved,reject的作用是:pending=>rejected

    再来一个简单的例子

    timeout(s){

    return new Promise((resolve,reject)=>{

    setTimeout(resolve,s*1000,"done");

    });

    }

    ....

    let pop=new POP();

    pop.timeout(2).then((v)=>{

    console.log(v);

    });

    你将在2s后看到如下输出:

    done

    Promise 封装 Ajax

    var toRequest=function (url) {

    var promise=new Promise((resolve,reject)=>{

    var client=new XMLHttpRequest();

    client.open("GET",url);

    client.onreadystatechange=handle;

    client.responseType="json";

    client.setRequestHeader("Accept","application/json");

    client.send();

    function handle() {

    if(this.readyState!==4){

    return;

    }

    if(this.status==200){

    resolve(this.response);

    }else{

    reject(new Error(this.statusText));

    }

    }

    });

    return promise;

    }

    toRequest("http://localhost:8046/info").then((v)=>{

    console.log(v);

    })

    </script>

    我已经事先写好了/info接口,它将返回一个json;你将看到如下输出:

    {  若要捕获error,你应该这样

    toRequest("http://localhost:8046/info").then((v)=>{

    console.log(v);

    }).catch((e)=>{

    console.log(e);

    });

    }

    上述例子中toRequest对XMLHttpRequest对象进行了封装,发出一个针对json数据的请求,并且返回一个promise对象,你将看到,在resolve和reject这两个函数中都携带了参数,前者成功返回数据后,将调用then(v=>{...}),其中v即使来自resolve的参数。它将返回一个respone。

    all()

    promise.all()方法用于将多个promise实例,包装成一个新的promise实例。

    例如:

    let promises=Promise.all([p1,p2,p3]...);

    该方法接受一个数组作为参数,p1...p3..都是promise实例,如果不是,也会将参数转化成promise实例,在进行处理。当然该参数也可以不是数组,但必须含有Iterator接口(可序列)。

    那么,他们之间的状态如何呢?

    正如上面的例子,promises的状态同时由p1,p2,p3...决定。

    他们间的关系如下图:

    p1...p3的状态变为fulfilled,promies才会变为fulfilled

    p1...p3的任何一个状态变为rejected,promies都会变为rejected

    来一个简单的例子:

    <script>

    var toRequest=function (url) {

    var promise=new Promise((resolve,reject)=>{

    var client=new XMLHttpRequest();

    client.open("GET",url);

    client.onreadystatechange=handle;

    client.responseType="json";

    client.setRequestHeader("Accept","application/json");

    client.send();

    function handle() {

    if(this.readyState!==4){

    return;

    }

    if(this.status==200){

    resolve(this.response);

    }else{

    reject(new Error(this.statusText));

    }

    }

    });

    return promise;

    }

    var promises=[1,2,3,4,5,6].map((page)=>{

    return toRequest("http://localhost:8046/info?page="+page);

    });

    Promise.all(promises).then(values=>{

    console.log(values);

    }).catch((errors)=>{

    console.log(errors);

    })

    </script>

    你将看到如下的输出:

    假设我停止了page等于4的相应又会如何呢?

    你将看到如下输出:

    关于Axios

    看到这里,你应该隐隐约约感觉到了,上述的东西视乎似曾相识,这不就是axios吗?是的。没错,axios就是利用http method来进行数据的交互的,它厉害的地方在于它能将服务器交互的操作包装成promise实例交给前端处理。然后你就能轻而易举的处理他们了。

    axios项目更多信息:https://www.kancloud.cn/yunye/axios/234845

    至此,promise的基本应用已经over,如果你感兴趣你甚至可以拿他跟rxjs做一下比较,他们哪些部分可以互通,或者他们有什么相似之处呢?主要差别在哪里呢?有时间我们再做探讨吧,如果你从未接触过promise,那么赶紧试试应用到你的项目吧!

    感谢关注~

    圣诞快乐~

    相关文章

      网友评论

          本文标题:JS Promise的应用

          本文链接:https://www.haomeiwen.com/subject/zjxeqctx.html