最近在学习es6的基本语法,总感觉promise对象好像之前接触过,不过在我学习它的时候,原来之前的一切都是错觉,真它娘的抽象。然后我现在整理一下我初步学习promise的一些见解。
promise语法
Promise编程的核心思想是如果数据就绪(promised),那么(then)做点什么。它也是异步编程的主要方式,同样的异步编程方式还有回调函数。异步编程我现在的理解就是一个函数的执行需要一个异步任务的返回结果,我们需要一种方法去实现该函数在异步任务之后去执行,并且拿到它的返回结果。
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。
resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为rejected), 在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
参数最终都会传递给下一个回调函数。
接下来我首先给大家写了一段回调函数代码
function s(callback) {
setTimeout(function() {
callback();
console.log(4)
}, 1000);
} function x() {
console.log(2);
}
s(x);
console.log(3); //3 2 4
在这需要注意,如果函数s里面是异步执行任务,它依然会将整个异步任务抛到任务队列,然后去执行同步任务,所以输出结果是3,2,4.如果全是同步任务,那么他会按顺序执行代码。这种方法的缺点是函数的嵌套如果太多,这种方法显得格外复杂并且难以实现。es6就提出了promise对象。
接下来请看promise代码
let p = new Promise(function(resolve, reject) {
//做一些异步操作
setTimeout(function() {
console.log('执行完成');
resolve('随便什么数据');
}, 2000);
});
let p1 = p.then(function(date) {
console.log(date);
}).catch(function(error) {
console.log(error)
console.log('代码错误'); //执行完成 随便什么数据
});
then方法可以追加两个函数作为参数,第一个函数是异步执行成功也就是resolved状态时要执行的代码,第二个函数可以不追加,它是异步执行错误时的执行的代码。
如果异步操作抛出错误,状态就会变为rejected,就会调用catch方法指定的回调函数,处理这个错误。另外,then方法指定的回调函数,如果运行中抛出错误,也会被catch方法捕获。
一般总是建议,Promise 对象后面要跟catch方法,这样可以处理 Promise 内部发生的错误。catch方法返回的还是一个 Promise 对象,因此后面还可以接着调用then方法。
还需要注意的是他的参数可以通过return方法传递给下一个回调函数
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
}
var p = timeout(3000).then((value) => {
console.log(value);
return value;
});
p.then((values) => (console.log(values + 's'))); // done dones
Promise.resolve()
有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用。
它的参数可以分为四种情况
1)参数是一个 Promise 实例
如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。
2)参数是一个thenable对象
thenable对象指的是具有then方法的对象,比如下面这个对象。
比如下面这段代码
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(function(value) {
console.log(value); // 42
});
3) 不带有任何参数
Promise.resolve方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。
所以,如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve方法。
const p = Promise.resolve();
p.then(function () {
// ...
});
4) 直接是初始数据类型
如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved。 直接当作参数传递给回调函数
const p = Promise.resolve('Hello');
p.then(function (s){
console.log(s)
});
// Hello