• Promise


    背景

    javascript是基于单线程事件循环的概念构建的,同一时刻只允许一个代码块执行。

    js引擎同一时刻只能执一个代码块,所以需要跟踪即将运行的代码。代码被放到一个任务队列中,每当一段代码准备执行时,都会被添加到任务队列中。当一段代码结束执行,事件循环会执行队列中的下一个任务。

    然而,浏览器的网络请求和事件都是异步执行的。ajax是典型的异步操作。如下jquery代码:

    $.ajax({
        data: data,
        url: url,
        success: function() {
            // code...
        },
        error: function() {
            // code..
        }
    })
    

    有没有更好的写法呢? 比如:

    ajaxGet('http://...')
        .ifSuccess(success)
        .ifFail(fail);
    

    这样就把执行代码和处理结果的代码分开处理。

    ES6提供了promise来处理异步执行,把执行代码和处理结果的代码清晰地分离了。当执行若干个异步任务,需要先做任务1,如果成功后再做任务2,任何任务失败则不再继续并执行错误处理函数.

    job1.then(job2)
        .then(job3)
        .catch(handleError);
    

    Promise的基本用法:

    生命周期

    每个promise都会经历一个生命周期:未完成(pending)和已完成。已完成的状态又分两种情况:操作成功(resolved)和操作失败(rejected)。

    创建promise

    1. 创建未完成的promise
    new Promise(function(resolve, reject) {})
    

    1. 创建操作成功的promise
    new Promise(function(resolve, reject) {
        resolve()
    })
    

    1. 创建操作失败的promise
    new Promise(function(resolve, reject) {
        reject()
    })
    

    所有的Promise都有then()方法,接收两个参数:操作成功的处理函数和操作失败的处理函数。只有当Promise的状态改变时,才会通过then()方法采取特定的操作。

    new Promise(function(resolve, reject) {
        resolve(42)
    }).then(function(value) {
        alert(value)
    }, function(value) {
        alert('err')
    });
    
    new Promise(function(resolve, reject) {
        reject(42)
    }).then(function(value) {
        alert(value)
    }, function(value) {
        alert('err')
    });
    

    通常,我们都采用链式调用的写法

    new Promise(function(resolve, reject) {
        resolve(42);
    }).then(function(value) {
        alert(value);
    }).catch(function() {
        alert('err');
    })
    
    new Promise(function(resolve, reject) {
        reject(42);
    }).then(function(value) {
        alert(value);
    }).catch(function() {
        alert('err');
    })
    

    串联promise

    Promise调用then()或catch()方法后都会返回一个操作成功状态的promise,这让我们可以继续对返回的promise进行处理。

    在完成处理程序中指定一个返回值,则可以沿着这条链继续传递数据。

    new Promise(function(resolve, reject) {
        reject(42)
    }).catch(function(value) {
    	console.log(value)
    	return value+1
    }).then(function(value) {
    	console.log(value)
    	return value+1
    });
    

    promise中返回promise

    promise只要创建就必须被捕获,否则浏览器会报错

    var p1 = new Promise(function(resolve, reject) {
    	reject('reject1')
    });
    var p2 = new Promise(function(resolve, reject) {
    	resolve('resolve1')
    })
    new Promise(function(resolve, reject) {
    	reject(60)
    }).then(function(value) {
    	console.log(value)
    	return p2
    }).catch(function(value) {
    	console.log(value)
    	return p1
    }).then(function(value) {
    	console.log(value)
    }).catch(function(value) {
    	console.log(value)
    })
    

    响应多个promise(具体内容请大家自学)

    promise提供了all()和race()来响应多个promise。

    all()方法当所有的Promise都被解决后返回的Promise才会被解决,只要有一个Promise被拒绝返回的Promise就会被拒绝。

    race()方法中传入的Promise会进行竞选,一旦来源Promise中有一个被解决,不管是resolve还是reject,所返回的 Promise 就会立刻被解决。

    Promise的异步任务执行

    我们在项目中使用axios来请求处理数据。axios就实现promise的异步请求。类似结构如下

    axios.get('/user?ID=12345')
        .then(function (response) {
            console.log(response);
        })
        .catch(function (error) {
            console.log(error);
        });
    
  • 相关阅读:
    location.replace与location.href,location.reload的区别
    转载关于KeyPress和KeyDown事件的区别和联系
    Javascript中call的使用
    按值和按引用的比较
    理解cookie的path和domain属性
    HTML的快速写法:Emmet和Haml
    SVN标准命令
    linux常用命令
    Android4.0(Phone)拨号启动过程分析(一)
    Activity生命周期
  • 原文地址:https://www.cnblogs.com/renzhiwei2017/p/7341446.html
Copyright © 2020-2023  润新知