Promise是一个解决函数异步执行的对象,有了这个对象,我们可以构造异步执行的操作。Promise对象可以通过链式调用的方式进行异步操作,语法如下:

如下代码,是一个简单的异步方法。
new Promise((resolve,reject)=>{
console.log("promise-> hello,world.this is promise. "+new Date());
setTimeout(()=>{
resolve("hello,world.this is promise. "+new Date());
},1000);
}).then((value)=>{
console.log("then -> "+value);
});
运行这段代码,得到结果如下所示:
通过Proimse我们很好的构建了一个异步操作,then中的函数始终都会在resolve()执行之后才开始执行。resolve()可以携带参数,这个参数到了then里面,就可以通过回调函数中的参数获取了,如题所示的value值,就是通过resolve(args)传递过来的。
另外,这里还有一个reject函数,就是当Promise内部执行出现异常,我们才会调用。这时候,一般then是不会执行的,这里如果要在reject后,继续执行then中的内容,我们需要在then中增加一个reject的函数处理。
new Promise((resolve,reject)=>{
console.log("promise-> hello,world.this is promise. "+new Date());
setTimeout(()=>{
reject("hello,world.this is promise. "+new Date());
},1000);
}).then((value)=>{
console.log("resolve-> "+value);
},(value)=>{
console.log("reject -> "+value);
});
执行结果如下:
一般情况下,为了简单,Promise只用来做异步处理,我们都不处理reject的情况,所以Promise写起来会很简单。比如:
new Promise(resolve=>{
console.log("promise-> hello,world.this is promise. "+new Date());
setTimeout(()=>{
resolve("hello,world.this is promise. "+new Date());
},1000);
}).then(value=>{
console.log("resolve-> "+value);
});
以上示例,从直观上感受到了Promise的强大,我们再也不用通过函数嵌套回调的方式来做异步操作了。如下所示的异步回调方法,一层套一层:
setTimeout(function(){
//todo
setTimeout(function(){
//todo
setTimeout(function(){
//todo
},1000);
},1000);
},1000);
嵌套回调,容易造成callback hell,Promise的then中,可以继续返回新的Promise,这样,可以构建一个简单的异步回调。而且写法更直观,更易于理解:
new Promise(resolve=>{
console.log("promise 1");
setTimeout(()=>{
resolve();
},1000);
}).then(()=>{
return new Promise(resolve=>{
console.log("promise 2");
setTimeout(()=>{
resolve();
},1000);
});
}).then(()=>{
return new Promise(resolve=>{
console.log("promise 3");
setTimeout(()=>{
resolve();
},1000);
});
});
Promise除了以上的用法,还可以有Promise.all().then()的用法,all()表示所有的操作均执行完成,再执行then()中的方法。而all()中的函数,不是顺序执行,而是同时执行。
const createPromise = (id) =>
new Promise(resolve=>
setTimeout(()=>{
console.log("promise->"+id+":"+new Date());
resolve();
},1000)
)
var tasks = [createPromise(1),createPromise(2),createPromise(3)];
console.log(tasks);
Promise.all(tasks).then(()=>console.log("all done."));
运行结果:
从运行结果看来,他们几乎是同一时刻,这种异步,虽然最终都会全部执行完成,再执行then()中的代码,但是all()中的函数并没有顺序执行。如果希望then()之前的函数都是顺序执行的,可以考虑通过reduce函数来实现。这里会比较难以理解。
const createPromise = (id) => () =>
new Promise(resolve=>
setTimeout(()=>{
console.log("promise->"+id+":"+new Date());
resolve();
},1000)
)
var tasks = [createPromise(1),createPromise(2),createPromise(3)];
console.log(tasks);
var doTask = tasks.reduce((prev,next)=>prev.then(()=>next()),Promise.resolve());
doTask.then(()=>console.log("all done."));
这里需要注意的是,我们的createPromise函数,不再返回的是Promise对象,而是一个函数,函数里面再返回Promise对象。运行我们的代码,截图如下:
可以看到,这里三个函数是按照顺序执行的,并没有同时执行,等到全部执行完成,最后执行then()中的方法。其实这种reduce写法,就回到了我们前面提到的Promise().then().then().then()的写法, 只不过使用reduce代码更简洁了,我们需要注意的是reduce()的数组是一个Function的数组,而不是Promise的数组。另外,reduce()方法的第二个参数,他是一个初始值,在这里就是Promise.resolve(),他表示一个动作已经执行完成,可以进行下一个动作了。
588





