这是我参与「第四届青训营 」笔记创作活动的第7天
什么是promise
所谓Promise,字面上可以理解为“承诺”,就是说A调用B,B返回一个“承诺”给A,然后A就可以在写计划的时候这么写:当B返回结果给我的时候,A执行方案S1,反之如果B因为什么原因没有给到A想要的结果,那么A执行应急方案S2,这样一来,所有的潜在风险都在A的可控范围之内了。
Promise规范如下:
- 一个promise可能有三种状态:等待(pending)、已完成(fulfilled)、已拒绝(rejected)
- 一个promise的状态只可能从“等待”转到“完成”态或者“拒绝”态,不能逆向转换,同时“完成”态和“拒绝”态不能相互转换
- promise必须实现
then方法(可以说,then就是promise的核心),而且then必须返回一个promise,同一个promise的then可以调用多次,并且回调的执行顺序跟它们被定义时的顺序一致 - then方法接受两个参数,第一个参数是成功时的回调,在promise由“等待”态转换到“完成”态时调用,另一个是失败时的回调,在promise由“等待”态转换到“拒绝”态时调用。同时,then可以接受另一个promise传入,也接受一个“类then”的对象或方法,即thenable对象。
peomise实现
/* promise的简单实现 */
class myPromise{
constructor (process) {
this.status = 'pending';
this.msg = '';
process(this.resolve.bind(this), this.reject.bind(this));
return this;
}
resolve (val) {
this.status = 'resolved';
this.msg = val;
}
reject (err) {
this.status = 'rejected';
this.msg = err;
}
then (resolve, reject) {
if(this.status == 'resolved')
resolve(this.msg);
if(this.status == 'rejected')
reject(this.msg);
}
}
//Test
var my_promise = new myPromise(function(resolve, reject) {
resolve('OK');
});
my_promise.then(function(val) {
console.log(`success: ${val}`);
}, function(err){
console.log(`failed: ${err}`);
}); //输出success: OK
promise应用
按照要求实现 mergePromise 函数,把传进去的函数数组按顺序先后执行,并且把返回的数据先后放到数组 data 中。 编写 JavaScript 代码,跑通如下测试用例
const timeout = (ms) =>
new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, ms);
});
const ajaxA = () =>
timeout(2000).then(() => {
console.log("A");
return A;
});
const ajaxB = () =>
timeout(1000).then(() => {
console.log("B");
return B;
});
const ajaxC = () =>
timeout(2000).then(() => {
console.log("C");
return C;
});
const mergePromise = (fetchArray) => {
// 在这里实现你的代码
};
//测试用例
mergePromise([fakeFetchWeather(), fakeFetchWeather(), fakeFetchWeather()]).then(
(data) => {
console.log("done");
console.log(data); // data 为 [A, B, C]
}
);
// 要求分别输出
// A
// B
// C
// done
// [A, B, C]
首先mergePromise里面需要有then方法,所以在mergePromise中必须return一个new promise,
然后根据传入的promise数组进行顺序执行,并只有执行完才能执行下一个;因此有如下代码
const mergePromise = async (fetchArray) => {
//在这里实现你的代码
return new Promise((resolve,reject)=>{
let promise = Promise.resolve()
let data = fetchArray.reduce((ans,item)=>{
promise = promise.then(item).then(res=>{
ans.push(res)
})
return ans
},[])
return promise.then(()=>resolve(data))
})
};
promise和async await的区别
- Promise的出现解决了传统callback函数导致的“地域回调”问题,但它的语法导致了它向纵向发展行成了一个回调链,遇到复杂的业务场景,这样的语法显然也是不美观的。而async await代码看起来会简洁些,使得异步代码看起来像同步代码,await的本质是可以提供等同于”同步效果“的等待异步返回能力的语法糖,只有这一句代码执行完,才会执行下一句。
- async await与Promise一样,是非阻塞的。
- async await是基于Promise实现的,可以说是改良版的Promise,它不能用于普通的回调函数。