Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的
function timeout(ms){
return new Promise((resolve,re)=>{
setTimeout(resolve,ms,'some thing is done');
})
}
timeout(1000).then((value)=>{
console.log(value)
})
let promise = new Promise((resovle,reject)=>{
console.log('resolve')
resovle();
});
promise.then((value)=>{
console.log('just test')
})
console.log('test aline ');
//resolve
//test aline
//just test
Promise 新建后立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出。
function loadImage(url){
return new Promise((resovle,reject)=>{
let image = new Image();
image.onload = function(){
resovle('load finish');
}
image.onerror = function(){
reject(new Error('can get the image from the url'+url));
}
image.src = url ;
})
}
loadImage('http://192.168.0.221:8080/browse/KFATP3-6416?filter=-1').then((value)=>{
console.log(value)
},()=>{
})
使用Promise包装了一个图片加载的异步操作。如果加载成功,就调用resolve方法,否则就调用reject方法。
new Promise((resolve, reject) => {
resolve(1);
console.log(2);
}).then(r => {
console.log(r);
});
调用resolve(1)以后,后面的console.log(2)还是会执行,并且会首先打印出来。这是因为立即 resolved 的 Promise 是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。
采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。
getJSON("/post/1.json").then(function(post) {
return getJSON(post.commentURL);
}).then(function funcA(comments) {
console.log("resolved: ", comments);
}, function funcB(err){
console.log("rejected: ", err);
});
如果 Promise 状态已经变成resolved,再抛出错误是无效的。Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误”
const promise = new Promise(function(resolve, reject) {
resolve('ok');
throw new Error('test');
});
promise
.then(function(value) { console.log(value) })
.catch(function(error) { console.log(error) });
// ok
Promise.all(),只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数
const p = Promise.all([p1, p2, p3]);
Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例
立即resolve的 Promise 对象,是在本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时。
setTimeout(function () {
console.log('three');
}, 0);
Promise.resolve().then(function () {
console.log('two');
});
console.log('one');
// one
// two
// three
setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log('one')则是立即执行,因此最先输出。
done()
Promise 对象的回调链,不管以then方法或catch方法结尾,要是最后一个方法抛出错误,都有可能无法捕捉到(因为 Promise 内部的错误不会冒泡到全局)。因此,我们可以提供一个done方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。
网友评论