이번에는 ES6에서 Promise를 사용하는 단계에 대해 자세히 설명하겠습니다. ES6에서 Promise를 사용할 때 주의 사항은 무엇입니까?
물론 이것이 풀스택으로 폭발했다는 뜻은 아닙니다. 전체 스택의 기술은 매우 집중되어 있습니다. 프런트엔드는 일부 HTML과 일부 상호 작용을 작성할 수 있을 뿐만 아니라 백엔드는 데이터베이스의 추가, 삭제, 확인 및 수정에 익숙합니다.
Node를 접해본 사람이라면 누구나 Node가 비동기(Async) 콜백으로 유명하다는 사실을 알아야 합니다. 비동기성은 프로그램의 실행 효율성을 향상시키지만 프로그램의 가독성도 떨어뜨립니다. 여러 개의 비동기 작업이 있고 후자의 작업에서 이전 작업에서 반환된 데이터를 실행해야 하는 경우 Node의 일반 실행 규칙에 따라 순서대로 비동기 작업은 일반적으로 레이어별로 중첩됩니다.
이 문제를 해결하기 위해 ES6에서는 Promise 구현을 제안했습니다.
의미
Promise object는 비동기 작업의 최종 완료(또는 실패)와 그 결과 값을 나타내는 데 사용됩니다. 간단히 말하면 비동기 작업을 처리하는 데 사용됩니다. 비동기 처리가 성공하면 성공한 작업이 실행됩니다. 비동기 처리가 실패하면 오류가 캡처되거나 후속 작업이 중지됩니다.
일반적인 표현은 다음과 같습니다.
new Promise( /* executor */ function(resolve, reject) { if (/* success */) { // ...执行代码 resolve(); } else { /* fail */ // ...执行代码 reject(); } } );
그 중 Promise의 매개변수 실행자는 확인(Resolve)과 거부(Reject)라는 두 개의 매개변수를 갖는 실행자 함수입니다. 그 내부에는 일반적으로 몇 가지 비동기 작업이 있습니다. 비동기 작업이 성공하면 Resolve()를 호출하여 인스턴스의 상태 를 이행, 즉 완료로 설정할 수 있습니다. 인스턴스의
상태를 이행으로 설정합니다. 상태가 거부됨, 즉 실패로 설정됩니다.
그리고 이 상태 변환 단방향이며 되돌릴 수 없으며 결정된 상태(이행/거부)를 초기 상태(보류)로 다시 전환할 수 없습니다. method
Promise.prototype.then()
Promise 객체에는 then()이 호출된 후 Promise 객체가 반환됩니다. 즉, 인스턴스화된 Promise 객체는 다음과 같습니다. 그리고 이 then() 메소드는 두 개의 함수를 받을 수 있습니다. 하나는 성공적인 처리 후의 함수이고 다른 하나는 오류 결과를 처리하는 함수입니다.
다음과 같습니다.
var promise1 = new Promise(function(resolve, reject) { // 2秒后置为接收状态 setTimeout(function() { resolve('success'); }, 2000); }); promise1.then(function(data) { console.log(data); // success }, function(err) { console.log(err); // 不执行 }).then(function(data) { // 上一步的then()方法没有返回值 console.log('链式调用:' + data); // 链式调用:undefined }).then(function(data) { // .... });
여기에서는 주로 promise1.then() 메서드가 호출된 후 반환된 Promise 개체의 상태에 중점을 둡니다. 보류 중, 이행 또는 거부됨?
var promise2 = new Promise(function(resolve, reject) { // 2秒后置为接收状态 setTimeout(function() { resolve('success'); }, 2000); }); promise2 .then(function(data) { // 上一个then()调用了resolve,置为fulfilled态 console.log('第一个then'); console.log(data); return '2'; }) .then(function(data) { // 此时这里的状态也是fulfilled, 因为上一步返回了2 console.log('第二个then'); console.log(data); // 2 return new Promise(function(resolve, reject) { reject('把状态置为rejected error'); // 返回一个rejected的Promise实例 }); }, function(err) { // error }) .then(function(data) { /* 这里不运行 */ console.log('第三个then'); console.log(data); // .... }, function(err) { // error回调 // 此时这里的状态也是fulfilled, 因为上一步使用了reject()来返回值 console.log('出错:' + err); // 出错:把状态置为rejected error }) .then(function(data) { // 没有明确指定返回值,默认返回fulfilled console.log('这里是fulfilled态'); });
Promise.prototype.catch()
catch()方法和then()方法一样,都会返回一个新的Promise对象,它主要用于捕获异步操作时出现的异常。因此,我们通常省略then()方法的第二个参数,把错误处理控制权转交给其后面的catch()函数,如下:
var promise3 = new Promise(function(resolve, reject) { setTimeout(function() { reject('reject'); }, 2000); }); promise3.then(function(data) { console.log('这里是fulfilled状态'); // 这里不会触发 // ... }).catch(function(err) { // 最后的catch()方法可以捕获在这一条Promise链上的异常 console.log('出错:' + err); // 出错:reject });
Promise.all()
Promise.all()接收一个参数,它必须是可以迭代的,比如数组。
它通常用来处理一些并发的异步操作,即它们的结果互不干扰,但是又需要异步执行。它最终只有两种状态:成功或者失败。
它的状态受参数内各个值的状态影响,即里面状态全部为fulfilled时,它才会变成fulfilled,否则变成rejected。
成功调用后返回一个数组,数组的值是有序的,即按照传入参数的数组的值操作后返回的结果。如下:
// 置为fulfilled状态的情况 var arr = [1, 2, 3]; var promises = arr.map(function(e) { return new Promise(function(resolve, reject) { resolve(e * 5); }); }); Promise.all(promises).then(function(data) { // 有序输出 console.log(data); // [5, 10, 15] console.log(arr); // [1, 2, 3] });
// 置为rejected状态的情况 var arr = [1, 2, 3]; var promises2 = arr.map(function(e) { return new Promise(function(resolve, reject) { if (e === 3) { reject('rejected'); } resolve(e * 5); }); }); Promise.all(promises2).then(function(data) { // 这里不会执行 console.log(data); console.log(arr); }).catch(function(err) { console.log(err); // rejected });
Promise.race()
Promise.race()和Promise.all()类似,都接收一个可以迭代的参数,但是不同之处是Promise.race()的状态变化不是全部受参数内的状态影响,一旦参数内有一个值的状态发生的改变,那么该Promise的状态就是改变的状态。就跟race单词的字面意思一样,谁跑的快谁赢。如下:
var p1 = new Promise(function(resolve, reject) { setTimeout(resolve, 300, 'p1 doned'); }); var p2 = new Promise(function(resolve, reject) { setTimeout(resolve, 50, 'p2 doned'); }); var p3 = new Promise(function(resolve, reject) { setTimeout(reject, 100, 'p3 rejected'); }); Promise.race([p1, p2, p3]).then(function(data) { // 显然p2更快,所以状态变成了fulfilled // 如果p3更快,那么状态就会变成rejected console.log(data); // p2 doned }).catch(function(err) { console.log(err); // 不执行 });
Promise.resolve()
Promise.resolve()接受一个参数值,可以是普通的值,具有then()方法的对象和Promise实例。正常情况下,它返回一个Promise对象,状态为fulfilled。但是,当解析时发生错误时,返回的Promise对象将会置为rejected态。如下:
// 参数为普通值 var p4 = Promise.resolve(5); p4.then(function(data) { console.log(data); // 5 }); // 参数为含有then()方法的对象 var obj = { then: function() { console.log('obj 里面的then()方法'); } }; var p5 = Promise.resolve(obj); p5.then(function(data) { // 这里的值时obj方法里面返回的值 console.log(data); // obj 里面的then()方法 }); // 参数为Promise实例 var p6 = Promise.resolve(7); var p7 = Promise.resolve(p6); p7.then(function(data) { // 这里的值时Promise实例返回的值 console.log(data); // 7 }); // 参数为Promise实例,但参数是rejected态 var p8 = Promise.reject(8); var p9 = Promise.resolve(p8); p9.then(function(data) { // 这里的值时Promise实例返回的值 console.log('fulfilled:'+ data); // 不执行 }).catch(function(err) { console.log('rejected:' + err); // rejected: 8 });
Promise.reject()
Promise.reject()和Promise.resolve()正好相反,它接收一个参数值reason,即发生异常的原因。此时返回的Promise对象将会置为rejected态。如下:
var p10 = Promise.reject('手动拒绝'); p10.then(function(data) { console.log(data); // 这里不会执行,因为是rejected态 }).catch(function(err) { console.log(err); // 手动拒绝 }).then(function(data) { // 不受上一级影响 console.log('状态:fulfilled'); // 状态:fulfilled });
总之,除非Promise.then()方法内部抛出异常或者是明确置为rejected态,否则它返回的Promise的状态都是fulfilled态,即完成态,并且它的状态不受它的上一级的状态的影响。
总结
大概常用的方法就写那么多,剩下的看自己实际需要再去了解。
解决Node回调地狱的不止有Promise,还有Generator和ES7提出的Async实现。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
위 내용은 ES6에서 Promise를 사용하는 단계에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!