• Promise 笔记


    1. Promise 创建

    Promise 对象是用于处理延时和异步调用场景,ES6中已经定稿,这个是未来的趋势

    初始化对象

    	new Promise(function(resolve, reject) {
    		resolve('success');
    	}).then(function(arg){
    		console.log(arg);//success
    	}).then(function(arg){
    		console.log(arg);//success
    	});
    

    对于Promise对象的链式处理方式

    	p.then(onFulfilled, onRejected);
    	p.then(function(value) {
    	
      	}, function(reason) {
      	
    	});
    
    2. 异常处理

    catch 和 Promise.prototype.then(undefined, onRejected) 是等同的,当需要注意的是其中catch和then的onRejected方法只能捕获一次异常

    	var p1 = new Promise(function(resolve, reject) {
            resolve('Success');
        });
    
        p1.then(function(value) {
            console.log(value); // "Success!"
            throw 'oh, no!'; // 抛出一个异常
        }).catch(function(e) {
            console.log(e); // "oh, no!" 异常被捕获
        }).then(function() {
            console.log('after a catch the chain is restored');
        }, function() {
            console.log('Not fired due to the catch'); // 再次绑定捕获也不会再次被触发
        });
    
        // The following behaves the same as above
        p1.then(function(value) {
            console.log(value); // "Success!"
            return Promise.reject('oh, no!'); // 再次发起一个异常
        }).catch(function(e) {
            console.log(e); // "oh, no!"
        }).then(function() {
            console.log('after a catch the chain is restored');
        }, function() {
            console.log('Not fired due to the catch'); //同样也不会被捕获
        });
    

    如果强制抛出了两次异常,例如:

    var pro = new Promise(function(resolve, reject){
        setTimeout(function(){
            reject(new Error('this is error'));
        },1000);
    }).then(function(arg){
        return Promise.reject('this is error 2');
    }).catch(function(arg){
        console.log(arg); // Error('this is error')
    }).catch(function(arg){
        console.log(arg); //undefined
    });
    

    这种场景下只有第一个异常会被捕获

    3. Promise.all 监听多个promise的状态
    // `delay`毫秒后执行resolve
    function timerPromisefy(delay) {
        return new Promise(function (resolve) {
            setTimeout(function () {
                resolve(delay);
            }, delay);
        });
    }
    var startDate = Date.now();
    // 所有promise变为resolve后程序退出
    Promise.all([
        timerPromisefy(1),
        timerPromisefy(32),
        timerPromisefy(64),
        timerPromisefy(128)
    ]).then(function (values) {
        console.log(Date.now() - startDate + 'ms');  // 約128ms
        console.log(values);    // [1,32,64,128]
    });
    

    必须等到所有的promise 的状态都变成FulFilled 之后才会触发all的成功方法

    4. Promise.race 监听多个promise
    // `delay`毫秒后执行resolve
    function timerPromisefy(delay) {
        return new Promise(function (resolve) {
            setTimeout(function () {
                resolve(delay);
            }, delay);
        });
    }
    // 任何一个promise变为resolve或reject 的话程序就停止运行
    Promise.race([
        timerPromisefy(1),
        timerPromisefy(32),
        timerPromisefy(64),
        timerPromisefy(128)
    ]).then(function (value) {
        console.log(value);    // => 1
    });
    

    只要有任意的一个promise对象变成FulFilled状态,then中的方法就会被调用

    再看看如果第一个promise执行完之后,其他的promise会不会继续执行

    var winnerPromise = new Promise(function (resolve) {
            setTimeout(function () {
                console.log('this is winner');
                resolve('this is winner');
            }, 4);
        });
    var loserPromise = new Promise(function (resolve) {
            setTimeout(function () {
                console.log('this is loser');
                resolve('this is loser');
            }, 1000);
        });
    // 第一个promise变为resolve后程序停止
    Promise.race([winnerPromise, loserPromise]).then(function (value) {
        console.log(value);    // => 'this is winner'
    });
    

    从结果来看其他的promise还是会继续执行的

    5. 使用reject而不是throw

    参考: http://liubin.org/promises-book/#not-throw-use-reject

    Promise的构造函数,以及被 then 调用执行的函数基本上都可以认为是在 try...catch 代码块中执行的,所以在这些代码中即使使用 throw ,程序本身也不会因为异常而终止。

    如果在Promise中使用 throw 语句的话,会被 try...catch 住,最终promise对象也变为Rejected状态。

    var promise = new Promise(function(resolve, reject){
        throw new Error("message");
    }).catch(function(error){
        console.error(error);// => "message"
    });
    

    使用reject的优点

    • 如果使用throw的话很难区分是我们主动抛出来的还是真正的其他异常,在Chrome中有 Pause On Caught Exceptions 不能区分
    • 在 then 中使用reject的方法
    var onRejected = console.error.bind(console);
    var promise = Promise.resolve();
    promise.then(function () {
        return Promise.reject(new Error("this promise is rejected"));
    }).catch(onRejected);
    

    这样在 then 方法中可以很方便的控制流程,同时传递任意的参数

    6. 最佳实践

    实现一个超时调用

    function delayPromise(ms) {
        return new Promise(function (resolve) {
            setTimeout(resolve, ms);
        });
    }
    
    delayPromise(100).then(function () {
        console.log("已经过了100ms!");
    });
    

    这样的超时调用更加的优雅

  • 相关阅读:
    opencv-0-项目启程
    [SketchUp]-绘制自己的家
    C51_PID 水温控制系统
    latex-列表环境
    nCOV 数据简要分析 (0326)
    引入OpenCV导致私有内存巨大
    【带着canvas去流浪(15)】threejs fundamentals翻译系列1-scene graph
    【一统江湖的大前端(9)】TensorFlow.js 开箱即用的深度学习工具
    【一统江湖的大前端(8)】matter.js 经典物理
    2019年12月前端面经及总结(西安,杭州)
  • 原文地址:https://www.cnblogs.com/koffee/p/5309079.html
Copyright © 2020-2023  润新知