回调地狱与promise

在开发JavaScript过程中,我们经常会用到异步操作和回调函数,但是,我们都知道,异步操作不能保证执行顺序是我们想象的那样,所以,就出现了“回调地狱”。

举个栗子:比如我现在要读取三个文件a.txt,b.txt,c.txt,并且让他的执行顺序必须为“先a,后b,最后c”,显然,我们不能用下面这种方法

var fs = require('fs')

fs.readFile('./data/a.txt','utf8',function (err, data) {
    if (err) {
        throw err
    }
    console.log(data)
})

fs.readFile('./data/b.txt','utf8',function (err, data) {
    if (err) {
        throw err
    }
    console.log(data)
})

fs.readFile('./data/c.txt','utf8',function (err, data) {
    if (err) {
        throw err
    }
    console.log(data)
})

执行结果:

我们执行多次,会发现,执行顺序是随机的,也就是说,他并不能像我们所想的一样,从上到下执行。

所以,我们一般会采用这种方式:

var fs = require('fs')

fs.readFile('./data/a.txt','utf8',function (err, data) {
    if (err) {
        throw err
    }
    console.log(data)
    fs.readFile('./data/b.txt','utf8',function (err, data) {
        if (err) {
            throw err
        }
        console.log(data)
        fs.readFile('./data/c.txt','utf8',function (err, data) {
            if (err) {
                throw err
            }
            console.log(data)
        })
    })

})


使用这样的方法,程序的执行顺序永远都是 “a,b,c” 。

但是,当我们必须要执行很多异步方法又必须保证顺序一定时,我们就有机会写出这样的代码:

怎么样?是不是感觉,很不美观,而且,在维护的时候,有可能一脸懵逼。

为了解决这个问题,ES6中的 promise 便可以“优雅”的解决这个问题了。

还是上面相同的案例,如果,我们用promise来重构的话,会变成这样。

var fs = require('fs')

var p1 = new Promise(function (resolve, reject) {
  fs.readFile('./data/a.txt', 'utf8', function (err, data) {
    if (err) {
      reject(err)
    } else {
      resolve(data)
    }
  })
})

var p2 = new Promise(function (resolve, reject) {
  fs.readFile('./data/b.txt', 'utf8', function (err, data) {
    if (err) {
      reject(err)
    } else {
      resolve(data)
    }
  })
})

var p3 = new Promise(function (resolve, reject) {
  fs.readFile('./data/c.txt', 'utf8', function (err, data) {
    if (err) {
      reject(err)
    } else {
      resolve(data)
    }
  })
})

p1
  .then(function (data) {
    console.log(data)
    // 当 p1 读取成功的时候
    // 当前函数中 return 的结果就可以在后面的 then 中 function 接收到
    // 当你 return 123 后面就接收到 123
    //      return 'hello' 后面就接收到 'hello'
    //      没有 return 后面收到的就是 undefined
    // 上面那些 return 的数据没什么卵用
    // 真正有用的是:我们可以 return 一个 Promise 对象
    // 当 return 一个 Promise 对象的时候,后续的 then 中的 方法的第一个参数会作为 p2 的 resolve
    // 
    return p2
  }, function (err) {
    console.log('读取文件失败了', err)
  })
  .then(function (data) {
    console.log(data)
    return p3
  })
  .then(function (data) {
    console.log(data)
  })

怎么样,是不是感觉,结构一下清晰了很多。

每一个方法相对“独立”,按照一定的顺序执行,而且改变执行顺序也变的简单了很多。

猜你喜欢

转载自blog.csdn.net/LitongZero/article/details/81607309