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);
    });
posted @ 2017-08-10 21:17  webLion200  阅读(197)  评论(0编辑  收藏  举报