>웹 프론트엔드 >JS 튜토리얼 >ES6의 Promise 사용법에 대한 자세한 설명

ES6의 Promise 사용법에 대한 자세한 설명

php中世界最好的语言
php中世界最好的语言원래의
2018-05-31 10:27:171172검색

이번에는 ES6에서 Promise를 사용하는 방법에 대해 자세히 설명하겠습니다. ES6에서 Promise를 사용할 때 Notes란 무엇인가요?

물론 이것이 풀스택으로 폭발했다는 뜻은 아닙니다. 전체 스택의 기술은 매우 집중되어 있습니다. 프런트엔드는 일부 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()를 호출하여 인스턴스의 상태 를 이행, 즉 완료로 설정할 수 있습니다. 인스턴스의

상태

를 이행으로 설정합니다. 상태가 거부됨, 즉 실패로 설정됩니다.

    Promise 객체는 공장 조립 라인으로 생각할 수 있습니다. 조립 라인의 경우 작업 기능으로 볼 때 상태는 세 가지뿐입니다. 하나는 초기 상태(방금 켜졌을 때)이고 다른 하나는 제품의 성공적인 처리 중 하나는 제품 처리 실패(일부 오류가 발생함)입니다. 마찬가지로 Promise 객체에도 세 가지 상태가 있습니다.
  1. pending: 미결정 상태라고도 불리는 초기 상태는 Promise를 초기화할 때 executor executor 함수를 호출한 후의 상태입니다.
  2. fulfilled: 완료 상태. 비동기 작업이 성공했음을 의미합니다.
  3. rejected: 실패 상태로, 비동기 작업이 실패했음을 의미합니다.

    전환할 수 있는 상태는 두 가지뿐입니다. 즉,
  1. 작업 성공: 보류 중 -> 이행
  2. 작업 실패: 보류 중 ->거부됨

그리고 이 상태 변환 단방향이며 되돌릴 수 없으며 결정된 상태(이행/거부)를 초기 상태(보류)로 다시 전환할 수 없습니다. 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 개체의 상태에 중점을 둡니다. 보류 중, 이행 또는 거부됨?

    반환된 Promise 개체의 상태는 다음과 같습니다. 주로 promise1을 기반으로 합니다. then() 메서드에서 반환되는 값은 대략 다음과 같은 상황으로 나눌 수 있습니다.
  1. then() 메서드에서 매개변수 값이 반환되면 반환된 Promise가 수신 상태가 됩니다.
  2. then() 메서드에서 예외가 발생하면 반환된 Promise가 거부됩니다.
  3. then() 메서드가 해결() 메서드를 호출하면 반환된 Promise가 수신 상태가 됩니다.
  4. then() 메서드가 discover() 메서드를 호출하면 반환된 Promise가 거부됩니다.
  5. then() 메서드가 알 수 없는 상태(보류 중)의 새 Promise 인스턴스를 반환하는 경우 반환된 새 Promise는 알 수 없는 상태입니다.
  6. 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中文网其它相关文章!

推荐阅读:

怎样使用Vue实现树形视图数据

如何使用JS求得数组的最小公倍数和最大公约数

위 내용은 ES6의 Promise 사용법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.