ES6基本的语法(十三) Promise

Promise

Promise 是一个对象,它代表了一个异步操作的最终完成或者失败。因为大多数人仅仅是使用已创建的 Promise 实例对象,所以本教程将首先说明怎样使用 Promise,再说明如何创建 Promise。
本质上 Promise 是一个函数返回的对象,我们可以在它上面绑定回调函数,这样我们就不需要在一开始把回调函数作为参数传入这个函数了。

一个 Promise 必然处于以下几种状态之一:

  • 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled): 意味着操作成功完成。
  • 已拒绝(rejected): 意味着操作失败。

待定状态的 Promise 对象要么会通过一个值被兑现(fulfilled),要么会通过一个原因(错误)被拒绝(rejected)。当这些情况之一发生时,我们用 promise 的 then 方法排列起来的相关处理程序就会被调用。如果 promise 在一个相应的处理程序被绑定时就已经被兑现或被拒绝了,那么这个处理程序就会被调用,因此在完成异步操作和绑定处理方法之间不会存在竞争状态。

基本使用

// Promise
// 需要传递一个执行期函数 executor function
let Op = new Promise(()=>{

});

Promise 和里面的函数是同步执行

// Promise
// 需要传递一个执行期函数 executor function
let Op = new Promise(()=>{
    // 里面的函数和 Promis 是同步执行
  console.log('0')
});
console.log('1')

// 先打印 0
// 后打印 1

从上面的例子中我们就知道 Promise 和里面的函数是同步执行

异步操作

// Promise
// 需要传递一个执行期函数 executor function
// 可以传递参数 resolve, reject 分来用来触发成功和失败的回调
// 使用 setTimeout 模拟异步操作
let op = new Promise((resolve, reject)=>{
    // 异步操作
  setTimeout(()=>{
        Math.random() * 100 > 60 ? resolve("ok"):reject('no')
  },1000)
});
// 异步执行
op.then((val)=>{
    console.log(val); // 输出ok
},(err)=>{
    console.log(err); // 输出no
})

在上面的代码中我们使用 setTimeout 来模拟一个异步请求,在 Promise 中有两个参数 resolvereject 分别用来触发成功和失败的回调。

// Promise
// 需要传递一个执行期函数 executor function
// 可以传递参数 resolve, reject 分来用来触发成功和失败的回调
let op = new Promise((resolve, reject)=>{
    console.log(0)
  resolve(1);
});
// 异步执行
op.then((val)=>{
    console.log(val); // 输出ok
},(err)=>{
    console.log(err);// 输出on
})
console.log(2);

// 输出 0 2 1

是因为 .then 是异步执行,被当成微任务。在上面我们也讲了 resolvereject 分别用来触发成功和失败的回调函数。

// Promise
// 需要传递一个执行期函数 executor function
// 可以传递参数 resolve, reject 分来用来触发成功和失败的回调
setTimeout(()=>{
        console.log('setTime');
  },0)
let op = new Promise((resolve, reject)=>{
    console.log(0)
  resolve(1);
});
// 异步执行
//
op.then((val)=>{
    console.log(val); // 输出ok
},(err)=>{
    console.log(err);// 输出on
})
console.log(2);

// 输出 0 2 1 setTime

我们都知道在 JavaScript 的任务队列中分为宏任务和微任务,我们通过 setTimeout() 或者触发事件、时间处理函数、ajax的回调都是放在宏任务。宏任务会被优先放到任务队列(task queue)里面去 ,微任务会被后被放入任务对列之中,但是微任务有优先执行权,所以微任务会优先被执行。

Promise 的链式操作

// Promise
// 需要传递一个执行期函数 executor function
// 可以传递参数 resolve, reject 分来用来触发成功和失败的回调
// 使用 setTimeout 模拟异步操作
let op = new Promise((resolve, reject)=>{
    // 异步操作
  setTimeout(()=>{
        Math.random() * 100 > 60 ? resolve("ok"):reject('no')
  },1000)
});
// 异步执行
op.then((val)=>{
    console.log(val); // 输出ok
},(err)=>{
    console.log(err); // 输出no
}).then((val)=>{
    console.log("ok then2"+val); // 输出ok
},(err)=>{
    console.log("no then2"+err); // 输出no
})

// 不管前面是输出的 ok 还是 no 都会输出 ok then2 undefined
// 前面的代码不抛出错误, 下面的都会输出 ok then2 undefined

在上面的代码中,不管是成功还是失败,都会输出 ok then2 undefined,除非前面的代码抛出错误

// Promise
// 需要传递一个执行期函数 executor function
// 可以传递参数 resolve, reject 分来用来触发成功和失败的回调
// 使用 setTimeout 模拟异步操作
let op = new Promise((resolve, reject)=>{
    // 异步操作
  setTimeout(()=>{
        Math.random() * 100 > 60 ? resolve("ok"):reject('no')
  },1000)
});
// 异步执行
op.then((val)=>{
    console.log(val); // 输出ok
  return 20
},(err)=>{
    console.log(err); // 输出no
  return 30
}).then((val)=>{
    console.log("ok then2"+val); // 输出ok
},(err)=>{
    console.log("no then2"+err); // 输出no
})

// 不管前面是输出的 ok 还是 no 都会输出 ok then2 20
// 前面的代码不抛出错误, 下面的都会输出 ok then2 20
// 如果抛出错误,这会输出 ok then2 30

上面的代码中加入了一个 return 20/30 会成为后面链式调用的参数,返回值会成为下一个 then 注册函数的执行参数。

如果返回的是一个 Promise 对象

// Promise
// 需要传递一个执行期函数 executor function
// 可以传递参数 resolve, reject 分来用来触发成功和失败的回调
// 使用 setTimeout 模拟异步操作
let op = new Promise((resolve, reject)=>{
    // 异步操作
  setTimeout(()=>{
        Math.random() * 100 > 60 ? resolve("ok"):reject('no')
  },1000)
});
// 异步执行
op.then((val)=>{
    console.log(val); // 输出ok
  return new Pormise((resolve,reject)=>{
    resolve('newPromise, ok')/reject('newPromise, no')
  })
},(err)=>{
    console.log(err); // 输出no
  return 30
}).then((val)=>{
    console.log("ok then2"+val); // 输出ok
},(err)=>{
    console.log("no then2"+err); // 输出no
})

// 不管前面是输出的 ok 还是 no 都会输出 ok then2 newPromise, ok

// 如果抛出错误,这会输出 ok then2 newPromise, no

下面的 .then 的执行结果会就根据第一个 .then 的结果去显示对应的内容,成功显示 ok then2 newPromise, ok,失败显示 ok then2 newPromise, no

处理回调地狱

let fs = require('fs');

function readFile(path){
    return new Promise((resolve, reject)=>{
    fs.readFile(path,'utf-8',(err,data)=>{
        if(data){
        resolve(data);
      }
    })
  })
}

readFile(path).then((data)=>{
    return readFile(data);
}).then((data)=>{
    return readFile(data);
}).then((data)=>{
    conosle.log(data);
})

你可能感兴趣的:(ES6基本的语法(十三) Promise)