Promise原理讲解(一)

407 阅读3分钟

1.同步和异步

同步

举个栗子,一个餐厅有三个客人,服务员给第一个客人A点完餐之后,等厨师做好菜,给客人A上菜之后,服务员再去服务下一位客人。这就是同步过程。


异步

举个栗子,同样是点餐,服务员给客人A点餐之后,告诉厨房,然后继续给B点餐,给C点餐。等点餐结束后,厨师说客人A的餐做好了,这个时候服务员给A上菜。这就是异步过程。


通过这两个栗子可知,同步的话肯定会浪费餐厅很多时间,这个时候就需要异步来解决这个问题。

在js的世界里,所有的代码执行就是单线程执行的。(单线程这里可以理解为一个餐厅只有一个服务员)。这个时候就需要异步来解决执行比较耗时的操作。

2.常见的异步操作

  • 回调函数
  • 事件监听
  • 发布/订阅
  • Promise对象

回调函数

请求1(function(请求结果1){
    处理请求结果1
})

这就是典型的回调函数。

如果说我们需要发送多个异步请求,并且每个异步请求之间有依赖关系。这个时候如果用回调来解决,就会陷入“回调地狱”。

请求1(function(请求结果1){
    请求2(function(请求结果2){
        请求3(function(请求结果3){
            请求4(function(请求结果4){
                请求5(function(请求结果5){
                    请求6(function(请求结果3){
                        ...
                    })
                })
            })
        })
    })
})

那么这段代码维护起来就很困难了。这个时候就可以选择用Promise完美的解决这个问题。

事件监听

发布/订阅

Promise对象

3. Promise

什么是promise

Promise是js里的一种异步解决方案之一。

Promise本身是一个类,可以用过new Promise来生成一个实例化对象。

let promise = new Promise();

也可以直接调用Promise类上的实例方法

Promise.resolve();

Promise状态

Promise相当于一个状态机,内部管理三种状态

  • pending (promise初始化状态为pending)
  • fulfilled (当调用resolve成功之后,状态 由pending转化为fulfilled)
  • rejected (当调用reject失败之后,状态有pending道rejected)


API以及用法

  • Promise.resolve
  • Promise.reject
  • Promise.race
  • Promise.all
  • Promise.prototype.then
  • Promise.prototype.catch
  • Promise.prototype.finally

Promise.prototype.then

promose.then接受两个参数,一个是成功的回调,一个是失败的回调

let promise = new Promise((reslove,reject)=>{
    resolve(1);
});
promise.then((data)=>{
    console.log(data);
},(error)=>{
    console.log(error);
});

Promise.prototype.catch

接受一个参数,就是失败的回调,跟promise.then(null,()=>{})是一样的

let promise = new Promise((resolve,reject) => {
    reject(1);
});
promise.then((data)=>{
    console.log(data);
},(error)=>{
    console.log(error);
}).catch((error)=>{
    console.log(error);
});

Promise.prototype.finally

接受一个参数,就是一个回调函数

var p = new Promise((resolve, reject) => {  
    reject(123);
});
p.then((data) => {  
    console.log('1', data);
}, (err) => {  
    console.log('2', err);
}).then((data) => {  
    console.log('11', data);
}, (err) => {  
    console.log('22', err);
}).catch((error) => {  
    console.log("catch", error);
}).finally(() => {  
    console.log("finally");
});

Promise.resolve

Promise.resolve("hello").then((data)=>{
    console.log(data);
});
//一样
new Promise((resolve,reject)=>{
    resolve("hello");
}).then((data)=>{
    console.log(data);
});

Promose.reject

Promise.reject("error").catch((error) => {  
    console.log(error);
});
//一样
new Promise((resolve, reject) => {  
    reject("error");
}).catch((error) => {  
    console.log(error);
});

Promose.all

假设read函数是读取文件。

Promise.all是等所有异步都执行执行完才会进入then,如果有一个一部失败,就会进入失败的回调

Promise.all([  read('./2.promise.js/a.txt'),  read('./2.promise.js/b.txt'),])
.then((arr) => {
  console.log(arr);
}, err => {  
    console.log(err);
})

Promose.race

多个 Promise 任务同时执行,返回最先执行结束的 Promise 任务的结果,不管这个 Promise 结果是成功还是失败

Promise.race([  read('./2.promise.js/a.txt'),  read('./2.promise.js/b.txt'),])
.then((arr) => {  
    console.log(arr);
}, err => {  
    console.log(err);
})

参考文献

ES6入门 之 Promise 对象 

PromiseA+规范