JavaScript Promise使用与实现-----如何使用?

如何使用promise

一般来说,我们处理异步事件都时候都是函数里面套函数,但是这样不仅不美观而且可读性非常差,就出现了回调地狱的问题

fs.readdir(source, function (err, files) {
  if (err) {
    console.log('Error finding files: ' + err)
  } else {
    files.forEach(function (filename, fileIndex) {
      console.log(filename)
      gm(source + filename).size(function (err, values) {
        if (err) {
          console.log('Error identifying file size: ' + err)
        } else {
          console.log(filename + ' : ' + values)
          aspect = (values.width / values.height)
          widths.forEach(function (width, widthIndex) {
            height = Math.round(width / aspect)
            console.log('resizing ' + filename + 'to ' + height + 'x' + height)
            this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {
              if (err) console.log('Error writing file: ' + err)
            })
          }.bind(this))
        }
      })
    })
  }
})

为了解决这个问题,ES6增加的promise函数就是一个异步回调的语法糖。
使用promise

let p = new Promise(function (resolve,rej) {
	fs.readdir(source, function (err, files) {
		if(err) {
			// 执行错误
			rej(err)
		} {
		// 执行成功回调函数
			resolve(files)
		}
	})
})
p.then(function(data){
// 执行成功回调函数	
},function(err){
// 执行错误回调函数
  console.log('Error finding files: ' + err)
})
// 这里可以使用catch,这样then就可以值接受成功回调函数
p.then(function(data){
	// 成功回调函数
}).catch(fucntion(err){
  console.log('Error finding files: ' + err)
})

需要知道是promise的方法都是可以链式回调的

除此之外,promise还有其他方法,建议阅读官方Promise MDN

  1. Promise.all()
    个人定义:这个是检测输入的一个Promise的实例数组,如果有一个返回错误的回调,则全部停止,进行错误回调函数执行

官方解释”Promise.all(iterable) 方法返回一个 Promise 实例,此实例在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise 的结果。

var p1 = new Promise(function(res,rej){
	res('p1')
}) 
var p2 = 45  
var p3 = Promise.resolve(3); // Promise.resolve(value)方法返回一个以给定值解析后的Promise 对象。
Promise.all([p1,p2,p3]).then((value)=>{
	console.log(value)  console.log(values); // [“p1”, 45, 3] 
})
// 输出 p1 45 3

这里p2为什么能够输出45?
从官方解释获取答案
iterable是一个可迭代对象,如 Array 或 String。
如果参数中包含非 promise 值,这些值将被忽略,但仍然会被直接放在返回数组中(如果 所有输入的 promise 完成的话)


  1. Promise.allSettled
    allSettled:全部被设置。统一设置回调函数,如果我们需要对2个Promise进行相同的回调处理的时候,我们可以将他们进行合并,同时设置。
const promise1 = Promise.resolve(3); // 成功
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));// 失败
Promise.allSettled([promise1, promise2]).
  then((results) => 
  results.forEach((result) => console.log(result.status)));// 输出异步处理结果 
  // expected output:
  // "fulfilled"
  // "rejected"

这里输出的是promise的状态,我们可以先了解下promise有三种状态

  • pending处理中
  • fulfilled成功回调
  • rejected失败回调

3.Promise.resolve()Promise.reject()这个返回设置好的成功回调或者失败回调的Promise对象,而参数输入的是解析之后返回的解析结果,如果你设置之后再次设置then的话,则会跟踪到对应的参数

var promise1 = Promise.resolve(123);

promise1.then(function(value) {
  console.log(value);
  // expected output: 123
});

不可以在自身的thenable 上调用Promise.resolve。这将导致无限递归,因为它试图展平无限嵌套的promise。
4. Promise.race([promise1,promise2……])
一旦参数中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。

var promise1 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 500, 'one');
});

var promise2 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then(function(value) {
  console.log(value);
  // 2个都是成功函数回调,但是promise2更加快
});
// 输出 2

就是输入的多个promise,只会进行处理第一个成功或者失败的promise
这个可以用在多个请求,但是我们只需要其中一个请求即可,所以可以使用race来进行异步请求,如果失败则重新请求,成功了就执行成功回调函数,这样就可以尽可能快速获得请求数据。因为他直接接受完成最快的异步请求。


5.Promise.finaly(function)这个设置的时无论成功与否都会调用的函数。

使用过程的问题

关于链式

var p1 = new Promise((res,rej)=>{
  res(11)
})
p1.then((data)=>{
  console.log(data) // 11
}).then(
  (data)=>{console.log(data)// undefined
})

输出结果

11
undefined

这里可以链式调用,因为then返回的是一个Promise对象,所以可以调用then,但是我们并不能多次获取到data值,因为then设置的回调是一个全新的Promise所以和前面无关,但是我们可以通过自己设置返回Promise来进行异步里面套异步


var p1 = new Promise((res,rej)=>{
  res('一次回调')
})
p1.then((data)=>{
  console.log(data) // 一次回调

  // return p1
  return new Promise((res,rej)=>{
    res('二次回调')
  })
}).then(
  (data)=>{console.log(data) // 二次回调
  })

输出结果

一次回调
二次回调

这里为什么返回一个新的Promise就可以实现异步嵌套呢?
这就是Promise设计的高明之处。我们在下一章来讨论这个问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值