Promise

208 阅读2分钟

promise是一种异步编码的解决方案,我们最开始的需求是这个样子的。
我们利用ajax去请求一些数据

$.ajax('url1',function(data1) {
    // 做一些数据处理,碰到第二个需要网络请求的地方
    $.ajax('url2',function(data2) {
        // 做一些数据处理,碰到第三个需要网络请求的地方
        $.ajax('url3',function(data3) {
            // 做一些数据处理,碰到第四个需要网络请求的地方
            $.ajax('url1',function(data1) {
               ...
})
    
})

})

})

这种就是回调地狱,我们处理的时候非常的麻烦,这个时候就轮到Promise出场了。
Promise的基本使用方式是

new Promise((reject,resolve) => {
resolve();
reject();
});

如你所见,resolve()和reject()都是函数,两者作为参数传入了箭头函数中来初始化Promise对象,
所以后来遇到类似的多个请求的时候使用Promise处理就比较简单,因为Promise把异步的过程和返回数据的处理分开,并且采用链式编程,大大简化了我们的代码。

new Promise((resolve, reject) => {
    // 做一些异步请求的处理,如果返回成功
    resolve(data);
    // 如果返回失败
    reject(data);
}).then(data => {
}).catch(data => {
})

补充:Promise的三种状态,pending:等待状态,fulfilled:成功,rejected失败

image.png

现在有了Promise之后如何处理刚刚的回调地狱的东西呢?
第一版代码

new Promise((resolve, reject) => {
  setTimeout(() => resolve('123'), 1000)
}).then((data) => {
  console.log(data);
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(data + 456)
    }, 1000);
  })
}).then((data) => {
  console.log(data);
  return new Promise(( reject,resolve) => {
    setTimeout(() => {
      resolve(data + 789)
    }, 1000);
  })
}).catch((err) => {
  console.log(err);
})

其中我们看到,我们利用setTimeout模拟异步操作,同时用console.log模拟对于数据的处理,同时进行新的请求。
在这个地方要注意一下,我尝试将resolve和reject换了位置,调用了一下发现这个和名字没什么关系,第二个位置就是失败的调用,尽管名字时resolve。
其实对于resolve函数是可以进行简写的。 比如我们的代码

new Promise((resolve, reject) => {
  setTimeout(() => resolve('123'), 1000)
}).then((data) => {
  console.log(data);
  return new Promise((resolve, reject) => {
      // 中间没有多余的异步请求
      resolve(data + 456)
  })
})

可以简写为

new Promise((resolve, reject) => {
  setTimeout(() => resolve('123'), 1000)
}).then((data) => {
  console.log(data);
  return Promise.resolve(data+'111')
})

再进行简化

new Promise((resolve, reject) => {
  setTimeout(() => resolve('123'), 1000)
}).then((data) => {
  console.log(data);
  return data + '111';
})