• 对于ES6中Promise的个人见解


    1.js中常见的异步

    • JavaScript可以响应用户的一些异步交互,比如单击鼠标和按键盘等操作。
    1 let button = document.getElementById("btn");
    2 buttom.onclick = function(event){
    3     console.log(“I was clicked !!")
    4 };
    • 在Node.js中更是使用大量的回调来代替事件来实现异步编程。

      node中读取文件方法及参数 

      fs.readFile(filename, [encoding], [callback(err,data)]);

    1 var fs = require('fs');
    2 fs.readFile('/Users/xiaosong/Desktop/example.txt', 'utf-8', function (err, data) {
    3     if (err) {
    4         console.log(err);
    5     } else {
    6         console.log(data);
    7     }
    8 });

    2.但是事件和回调并不能满足需求,比如像并行执行两个异步操作,两个操作结束时都通知你,或者说同时进行两个异步操作,

     想要优先完成的通知你。想要满足这些你可能写很多的回调,而Promise可以很好的解决这些问题。

    3.那么什么是Promise呢?

    • 我的理解就是它只是另一种异步编程的选择,就像事件和回调函数一样指定稍后执行的代码,但是它可以指示代码是否成功的执行,基于成功和失败的状态分别执行什么,更加易于理解和调试。
     1 let fs = require("fs");
     2 function readFile(filename){
     3     return new Promise(function(resolve,reject){
     4         // Promise只接受一个参数叫做执行器函数,接受resolve和reject两个函数
     5         fs.readFile(filename,{encoding:"utf-8"},function(err,data){
     6             //错误优先,检查是否出错
     7             if(err){
     8                 reject(err);
     9                 return;
    10             }
    11             //成功读取文件
    12             resolve(data);
    13         });
    14     });
    15 };
    16 let promise = readFile("/Users/xiaosong/Desktop/example.txt");
    17 promise.then(function(data){
    18     //完成
    19     console.log(data);
    20 },function(err){
    21     //拒绝
    22     console.log(err.message);
    23 });

    输出的是---->就算失败也要摆出豪迈的姿态。<----    很明显这是陈咬金的台词!!

    这就是一个完整的Promise了。看到这里感觉估计还是蒙逼的请让在下为你细细道来

    let promise = new Promise(function(reslove,reject){
        console.log("A");
        reslove();
    });
    promise.then(function(){
        console.log("B");
    });
    console.log("C");

    输出ACB

    • 为什么会这样输出呢? 就是因为执行器中调用了resolve();
       触发了一个异步的操作then()与执行器不同没有立即执行,它总是等执行器完成后被添加到任务队列的末尾。
    4. 每一个Promise都会经历一个短暂的生命周期
    •Pending  进行中的状态;

    当这个状态结束后会进入下面两种状态之一:

    •Fulfiled Promise异步操作成功
    •Rejected 由于某些缘故出错了,Promise异步操作未能成功
    内部有[[PromiseState]]这个属性来表示这三种状态,但是这个属性又没有在Promise上暴漏出来所以并不能对它进行编程来检测Promise所处的状态,那么怎么办呢。
    5. 但还是有办法的,当Promise状态改变时可以通过then()这个方法来采取特定的行为,所有的Promise都有then()方法;
    •then()有两个参数
    •第一参数是状态为Fulfilled时调用的函数
    •第二参数是状态为Rejected时调用的函数
    与异步相关对应状态的数据都会传给对应的函数
    这两个参数都是可选的,可以按照任意的组合来监听Promise
    promise.then(function(data){
        //完成
        console.log(data);
    },function(err){
        //拒绝
        console.log(err.message);
    });
    promise.then(null,function(err){
        //拒绝
        console.log(err.message);
    });
    
    

    那么我以上讲的创建的都是未完成的Promise,可能乍一看来创建未完成的Promise尚且有意义但是创建已处理的有什么意义呢!

    let promise = Promise.reject("我是一段安静的文字,你不会知道我是安静的");
    promise.catch(function(value){
        console.log(value); // 我是一段安静的文字,你不会知道我是安静的
    });
    let promise = Promise.resolve("我是一段安静的文字,你不会知道我是安静的");
    promise.then(function(value){
        console.log(value); // 我是一段安静的文字,你不会知道我是安静的
    });
    •这就是重点了,如果向Promise.resolve()或者Promise.reject()传入Promise那么这个Promise会直接返回,如果传入的不是Promise的thenable对象则会创建一个新的Promise对象并在then()函数中被调用。
    •那什么又是thenable对象呢?

    有then()方法并且接受resolve和reject两个参数的普通对象:

    let thenable = {
        then: function(resolve, reject){
            resolve("我是一段开心的文字,没人知道我在乐啥");
        }
    };
    let promise = Promise.resolve(thenable);
    promise.then(function(value){
        console.log(value) //我是一段开心的文字,没人知道我在乐啥
    });
    •好吧你可能感觉这还是没有什么卵用但是要知道在ECMAScript6之前有很多库是支持Promise的且使用了thenable对象,这个可以帮助转换为正式的Promise对象,管他真假Promise先塞进去变成真的再说。

        <script>
            function MyPromise(func){
                var deferred = $.Deferred();
                func(deferred.resolve, deferred.reject);
                return deferred.promise();
            };
            new MyPromise(function(resolve, reject){
                console.log(1);
                resolve();
                console.log(2);            
            }).then(function(){
                console.log(3);
            });
            console.log(4);
            // 在jquery1.6.4的版本下输出是1234
            // 在jquery3.2.1中输出是 1243
        </script>

    在ES6中

    new Promise(function (resolve,reject) {
        console.log(1);
        resolve();
        console.log(2);
    }).then(function () {
        console.log(3);
    });
    console.log(4);
    // 这里同样输出的也是1243

    从这里看JQuery也是在向标准看齐的。

    6. Promise还可以串联调用
    就像这样:
    promise.then().then().then()……
    let promise = new Promise(function(resolve,reject){
        resolve("淡定的文字");
    });
    
    promise.then(function(value){
        console.log(value);
        return value + ",不开心"
    }).then(function(value){
        console.log(value);
        return value + "怎么办"
    }).then(function(value){
        console.log(value);
        throw new Error("又错了");
    }).catch(function(err){
        console.log(err.message);
    });

    输出:

      淡定的文字
      淡定的文字,不开心
      淡定的文字,不开心怎么办
      又错了

    我是这样理解的每一次调用then()后都会再一次返回一个新的promise,这样新的Promise就又会接着调用后面的then()就这样一直下去直到最后一个then();

    promise的链上最后做好要加上一个处理拒绝处理程序then或者是catch()这样方便处理在链上可能发生的错误;
    但是这样又会出现一个问题怎样把链上的上一then()的数据传给下面一个then呢,虽然理解起来他是生成的是新的Promise,但总不能再写一个resolve()吧,很明显不行只能使用return 把下一个then()要使用的数据使用return 传过去。
    7.之前的都是对单个Promise响应,也可以监听多个Promise进行响应来决定下一步的执行,Promise.all();
    接收的是一个由多个Promise组成的数组,只有这些Promise都成功完成并返回一个Promise才会被完成。
     
    let p1 = new Promise(function(resolve,reject){
        resolve("OK one");
    });
    
    let p2 = new Promise(function(resolve,reject){
        reject("refuse two");
    });
    
    let p3 = new Promise(function(resolve,reject){
        resolve("OK three");
    });
    
    let p4 = Promise.all([p1,p2,p3]);
    
    p4.catch(function(value){
        console.log(Array.isArray(value)); //false
    })
    let p1 = new Promise(function(resolve,reject){
        resolve("OK one");
    });
    
    let p2 = new Promise(function(resolve,reject){
        resolve("refuse two");
    });
    
    let p3 = new Promise(function(resolve,reject){
        resolve("OK three");
    });
    
    let p4 = Promise.all([p1,p2,p3]);
    
    p4.then(function(value){
        console.log(Array.isArray(value)); //true
    })

    8.能够监听多个Promise的方法还有Promise.race();它的参数和Promise.all()是相同的,返回的也是一个Promise,但是使用这个方法监听的是最先被解决的Promise,谁先被解决就返回谁,无需等到所有的Promise都完成。

    let p1 = new Promise(function(resolve,reject){
        setTimeout(function(){
        resolve("OK one");    
        },200);
    });
    
    let p2 = new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve("OK two");    
        },100);
    });
    
    let p3 = new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve("OK three");    
        },300);
    });
    
    let p4 = Promise.race([p1,p2,p3]);
    
    p4.then(function(value){
        console.log(value); //two
    })

    ok 这就是我对promise的浅见。

    ---恢复内容结束---

    1.js中常见的异步

    • JavaScript可以响应用户的一些异步交互,比如单击鼠标和按键盘等操作。
    1 let button = document.getElementById("btn");
    2 buttom.onclick = function(event){
    3     console.log(“I was clicked !!")
    4 };
    • 在Node.js中更是使用大量的回调来代替事件来实现异步编程。

      node中读取文件方法及参数 

      fs.readFile(filename, [encoding], [callback(err,data)]);

    1 var fs = require('fs');
    2 fs.readFile('/Users/xiaosong/Desktop/example.txt', 'utf-8', function (err, data) {
    3     if (err) {
    4         console.log(err);
    5     } else {
    6         console.log(data);
    7     }
    8 });

    2.但是事件和回调并不能满足需求,比如像并行执行两个异步操作,两个操作结束时都通知你,或者说同时进行两个异步操作,

     想要优先完成的通知你。想要满足这些你可能写很多的回调,而Promise可以很好的解决这些问题。

    3.那么什么是Promise呢?

    • 我的理解就是它只是另一种异步编程的选择,就像事件和回调函数一样指定稍后执行的代码,但是它可以指示代码是否成功的执行,基于成功和失败的状态分别执行什么,更加易于理解和调试。
     1 let fs = require("fs");
     2 function readFile(filename){
     3     return new Promise(function(resolve,reject){
     4         // Promise只接受一个参数叫做执行器函数,接受resolve和reject两个函数
     5         fs.readFile(filename,{encoding:"utf-8"},function(err,data){
     6             //错误优先,检查是否出错
     7             if(err){
     8                 reject(err);
     9                 return;
    10             }
    11             //成功读取文件
    12             resolve(data);
    13         });
    14     });
    15 };
    16 let promise = readFile("/Users/xiaosong/Desktop/example.txt");
    17 promise.then(function(data){
    18     //完成
    19     console.log(data);
    20 },function(err){
    21     //拒绝
    22     console.log(err.message);
    23 });

    输出的是---->就算失败也要摆出豪迈的姿态。<----    很明显这是陈咬金的台词!!

    这就是一个完整的Promise了。看到这里感觉估计还是蒙逼的请让在下为你细细道来

    let promise = new Promise(function(reslove,reject){
        console.log("A");
        reslove();
    });
    promise.then(function(){
        console.log("B");
    });
    console.log("C");

    输出ACB

    • 为什么会这样输出呢? 就是因为执行器中调用了resolve();
       触发了一个异步的操作then()与执行器不同没有立即执行,它总是等执行器完成后被添加到任务队列的末尾。
    4. 每一个Promise都会经历一个短暂的生命周期
    •Pending  进行中的状态;

    当这个状态结束后会进入下面两种状态之一:

    •Fulfiled Promise异步操作成功
    •Rejected 由于某些缘故出错了,Promise异步操作未能成功
    内部有[[PromiseState]]这个属性来表示这三种状态,但是这个属性又没有在Promise上暴漏出来所以并不能对它进行编程来检测Promise所处的状态,那么怎么办呢。
    5. 但还是有办法的,当Promise状态改变时可以通过then()这个方法来采取特定的行为,所有的Promise都有then()方法;
    •then()有两个参数
    •第一参数是状态为Fulfilled时调用的函数
    •第二参数是状态为Rejected时调用的函数
    与异步相关对应状态的数据都会传给对应的函数
    这两个参数都是可选的,可以按照任意的组合来监听Promise
    promise.then(function(data){
        //完成
        console.log(data);
    },function(err){
        //拒绝
        console.log(err.message);
    });
    promise.then(null,function(err){
        //拒绝
        console.log(err.message);
    });
    
    

    那么我以上讲的创建的都是未完成的Promise,可能乍一看来创建未完成的Promise尚且有意义但是创建已处理的有什么意义呢!

    let promise = Promise.reject("我是一段安静的文字,你不会知道我是安静的");
    promise.catch(function(value){
        console.log(value); // 我是一段安静的文字,你不会知道我是安静的
    });
    let promise = Promise.resolve("我是一段安静的文字,你不会知道我是安静的");
    promise.then(function(value){
        console.log(value); // 我是一段安静的文字,你不会知道我是安静的
    });
    •这就是重点了,如果向Promise.resolve()或者Promise.reject()传入Promise那么这个Promise会直接返回,如果传入的不是Promise的thenable对象则会创建一个新的Promise对象并在then()函数中被调用。
    •那什么又是thenable对象呢?

    有then()方法并且接受resolve和reject两个参数的普通对象:

    let thenable = {
        then: function(resolve, reject){
            resolve("我是一段开心的文字,没人知道我在乐啥");
        }
    };
    let promise = Promise.resolve(thenable);
    promise.then(function(value){
        console.log(value) //我是一段开心的文字,没人知道我在乐啥
    });
    •好吧你可能感觉这还是没有什么卵用但是要知道在ECMAScript6之前有很多库是支持Promise的且使用了thenable对象,这个可以帮助转换为正式的Promise对象,管他真假Promise先塞进去变成真的再说。

        <script>
            function MyPromise(func){
                var deferred = $.Deferred();
                func(deferred.resolve, deferred.reject);
                return deferred.promise();
            };
            new MyPromise(function(resolve, reject){
                console.log(1);
                resolve();
                console.log(2);            
            }).then(function(){
                console.log(3);
            });
            console.log(4);
            // 在jquery1.6.4的版本下输出是1234
            // 在jquery3.2.1中输出是 1243
        </script>

    在ES6中

    new Promise(function (resolve,reject) {
        console.log(1);
        resolve();
        console.log(2);
    }).then(function () {
        console.log(3);
    });
    console.log(4);
    // 这里同样输出的也是1243

    从这里看JQuery也是在向标准看齐的。

    6. Promise还可以串联调用
    就像这样:
    promise.then().then().then()……
    let promise = new Promise(function(resolve,reject){
        resolve("淡定的文字");
    });
    
    promise.then(function(value){
        console.log(value);
        return value + ",不开心"
    }).then(function(value){
        console.log(value);
        return value + "怎么办"
    }).then(function(value){
        console.log(value);
        throw new Error("又错了");
    }).catch(function(err){
        console.log(err.message);
    });

    输出:

      淡定的文字
      淡定的文字,不开心
      淡定的文字,不开心怎么办
      又错了

    我是这样理解的每一次调用then()后都会再一次返回一个新的promise,这样新的Promise就又会接着调用后面的then()就这样一直下去直到最后一个then();

    promise的链上最后做好要加上一个处理拒绝处理程序then或者是catch()这样方便处理在链上可能发生的错误;
    但是这样又会出现一个问题怎样把链上的上一then()的数据传给下面一个then呢,虽然理解起来他是生成的是新的Promise,但总不能再写一个resolve()吧,很明显不行只能使用return 把下一个then()要使用的数据使用return 传过去。
    7.之前的都是对单个Promise响应,也可以监听多个Promise进行响应来决定下一步的执行,Promise.all();
    接收的是一个由多个Promise组成的数组,只有这些Promise都成功完成并返回一个Promise才会被完成。
     
    let p1 = new Promise(function(resolve,reject){
        resolve("OK one");
    });
    
    let p2 = new Promise(function(resolve,reject){
        reject("refuse two");
    });
    
    let p3 = new Promise(function(resolve,reject){
        resolve("OK three");
    });
    
    let p4 = Promise.all([p1,p2,p3]);
    
    p4.catch(function(value){
        console.log(Array.isArray(value)); //false
    })
    let p1 = new Promise(function(resolve,reject){
        resolve("OK one");
    });
    
    let p2 = new Promise(function(resolve,reject){
        resolve("refuse two");
    });
    
    let p3 = new Promise(function(resolve,reject){
        resolve("OK three");
    });
    
    let p4 = Promise.all([p1,p2,p3]);
    
    p4.then(function(value){
        console.log(Array.isArray(value)); //true
    })

    8.能够监听多个Promise的方法还有Promise.race();它的参数和Promise.all()是相同的,返回的也是一个Promise,但是使用这个方法监听的是最先被解决的Promise,谁先被解决就返回谁,无需等到所有的Promise都完成。

    let p1 = new Promise(function(resolve,reject){
        setTimeout(function(){
        resolve("OK one");    
        },200);
    });
    
    let p2 = new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve("OK two");    
        },100);
    });
    
    let p3 = new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve("OK three");    
        },300);
    });
    
    let p4 = Promise.race([p1,p2,p3]);
    
    p4.then(function(value){
        console.log(value); //two
    })

    ok 这就是我对promise的浅见。

  • 相关阅读:
    Poj2104-K-th Number(主席树)
    Poj3237-Tree(树链剖分)
    Spoj QTREE(树链剖分)
    字符串算法
    网络流算法
    利用DiDiSoft OpenPGP Library for .NET 程序加密解密文件
    利用GPG4Win加密解密文件
    .NET Standard和.NET Framework的区别【转】
    Aras学习笔记 (6) Aras Client Side代码弹出标准ItemType内容窗口
    WebClient使用DownloadFile下载文件超时的解决办法
  • 原文地址:https://www.cnblogs.com/xiao-song/p/7436446.html
Copyright © 2020-2023  润新知