>  기사  >  웹 프론트엔드  >  Promise를 시작하기 위해 알아야 할 사항

Promise를 시작하기 위해 알아야 할 사항

php中世界最好的语言
php中世界最好的语言원래의
2018-03-19 14:27:071373검색

이번에는 Promise를 시작할 때 꼭 알아야 할 주의 사항에 대해 알려드리겠습니다. 실제 사례를 살펴보겠습니다.

Promise는 비동기 프로그래밍을 위한 솔루션입니다. 구문론적으로 Promise는 비동기 작업에 대한 메시지를 얻을 수 있는 개체입니다.

Promise

PromiseConstructor의 기본 사용법은 함수를 매개변수로 허용하며 함수의 두 매개변수는 확인(Resolve)과 거부(Reject)입니다. 이는 JavaScript 엔진에서 제공하는 두 가지 기능입니다.

  • resolve 함수의 역할은 Promise 객체의 상태를 "미완료"에서 "성공"(즉, 보류에서 해결로)으로 변경하고 비동기 작업이 성공할 때 호출되며 그 결과를 사용하는 것입니다. 매개변수가 전달됨에 따라 비동기 작업이 수행됩니다.

  • reject 함수의 기능은 Promise 개체의 상태를 "미완성"에서 "실패"로 변경하는 것입니다(즉, 보류 중에서 거부됨으로). 비동기 작업이 실패하면

    가 호출되고 비동기 작업을 보고합니다. 작업 오류는 매개변수로 전달됩니다.

  • then 메소드는 두 개의
  • 콜백 함수

    를 매개변수로 받아들일 수 있습니다. 첫 번째 콜백 함수는 Promise 객체의 상태가 Resolved로 변경될 때 호출되고, 두 번째 콜백 함수는 Promise 객체의 상태가 Reject로 변경될 때 호출됩니다.

    var promise = new Promise(    //异步执行,Promise对象创建后会被立即执行
        function (resolve,reject) {        //耗时很长的异步操作  if('异步处理成功') {  
            resolve();    //数据处理成功时调用  } else {
            reject();    //数据处理失败时调用    }
            
        }
    )//Promise实例生成以后,可以用then方法分别指定Resolved状态和Reject状态的回调函数。promise.then(    function A() {        //数据处理成功后执行    },    function B() {        //数据处理失败后执行    }
    )
  • 비동기 작업 성공 및 비동기 작업 실패 기능의 실행 프로세스를 시뮬레이션하는 간단한 예를 들어보겠습니다.
console.log('starting' promise =  Promise("2秒后,我运行了"'异步操作成功了');     
        
    }, 2000'异步操作成功后执行我:''异步操作失败后执行我:''我也运行了'
知代码3处的return 'hello' 语句在新建的new Promise对象中并没有被当作参数返回给then()函数内.那么会不会返回给promise了呢?我们用一段代码来测试一下
console.log('starting');var promise = new Promise(function(resolve, reject) {  
    setTimeout(function() { 
        console.log("2秒后,我运行了");
        resolve('异步操作成功了');     //1
        //reject('异步操作失败了');    //2
        return 'hello';
    }, 2000) 
    
})
promise.then(function (value) { 
    console.log('异步操作成功后执行我:',value);
},function (value) {
    console.log('异步操作失败后执行我:',value);
}
)
console.log('我也运行了');
console.log(promise);
setTimeout(function () {
    console.log('5秒后,我执行了');
    console.log(promise);
},5000);//starting//我也运行了//Promise { pending }  //[[PromiseStatus]]:"pending"  //[[PromiseValue]]:undefined  //proto:Promise {constructor: , then: , catch: , …}//2秒后,我运行了//异步操作成功后执行我: 异步操作成功了//5秒后,我执行了//Promise { resolved }  //[[PromiseStatus]]:"resolved"  //[[PromiseValue]]:"异步操作成功了"  //proto:Promise {constructor: , then: , catch: , …}

실행 결과를 보면 promise 변수가 여전히 새 Promise 객체의 인스턴스임을 알 수 있습니다. 따라서 return 문이 실행되더라도 Promise 인스턴스에는 아무런 영향을 미치지 않으며 이는 존재하지 않는 것과 같습니다.

위에서 테스트한 코드에서 볼 수 있듯이 Promise 객체는 다음과 같은 두 가지 특성을 가지고 있습니다.

  (1) 물체의 상태는 외부 세계의 영향을 받지 않습니다. Promise 객체는 비동기 작업을 나타내며 보류(진행 중), 해결(완료, 이행이라고도 함), 거부(실패)의 세 가지 상태를 갖습니다.

비동기 연산의 결과만이 현재 상태가 어떤 상태인지 판단할 수 있으며,
   (2) 한번 상태가 변경되면 다시 변경되지 않으며 언제든지 결과를 얻을 수 있습니다. Promise 객체의 상태가 변경되는 경우는 Pending에서 Resolved로, Pending에서 Rejected로 두 가지뿐입니다. 이 두 가지 상황이 발생하는 한 상태는 굳어져 다시는 변하지 않고 항상 이 결과를 유지하게 될 것입니다. 이미 변경이 발생한 경우에도 Promise 객체에 콜백 함수를 추가하면 즉시 결과를 얻을 수 있습니다. 이는 이벤트와는 전혀 다른 이벤트의 특징은 놓치고 다시 들으면 결과가 나오지 않는다는 점입니다.

resolve(value) VS 해결(Promise)

비동기 작업이 성공하면 확인 함수

를 호출합니다. 그 기능은 Promise 객체의 상태를 Pending에서 Resolved로 변경하고 결과를 전달하는 것입니다. 매개변수로 비동기 작업 then() 메서드의 첫 번째 함수에 형식 매개변수 를 제공합니다. 그러면 전달된 매개변수가 값인 경우와 전달된 매개변수가 Promise 객체인 경우의 차이점은 무엇인가요? 예를 살펴보겠습니다.

전달된 매개변수가 다음 값인 경우:

var time = new Date();var promise = new Promise(function(resolve, reject) {  
    setTimeout(function() { 
        console.log("1秒后,我运行了");
        resolve('异步操作成功了');     //1
    }, 2000) 
    
}).then(function (value) {
    console.log(value,new Date() - time);
})//执行的输出结果为://2秒后,我运行了//异步操作成功了 1002

약 1초 정도 후에 해결 상태의 콜백 메소드에서 위 주석의 내용을 인쇄하는 것을 볼 수 있습니다. 해결 메서드를 통해 작업 결과를 전달한 다음 이 결과를 콜백 메서드에서 사용할 수 있습니다.

Resolve에서 Promise 인스턴스를 전달하면 어떻게 되나요?

 time =  promise =  Promise("2秒后,我运行了"'异步操作成功了');     2000 promise2 =  Promise(1000 Date() -

promise2는 2초 후에 결과를 인쇄합니다. 이상한데요, promise2가 1초 후에 실행되도록 설정하지 않았나요?

간단히 말하면 promise2의solve() 함수가 promise 객체를 전달하기 때문입니다. 이때 promise 객체의 상태가 promise의 상태를 결정하고 반환 값이 promise에 전달됩니다.

Promise/A+는

[[Resolve]](promise, x)

2.3.2를 규정합니다. x가 약속 인스턴스이면 x 상태가 약속 상태로 사용됩니다

2.3.2.1 x 상태가 보류 중이면 상태입니다. x 상태가 변경될 때까지 약속도 보류 중입니다.

  2.3.2.2. x의 상태가 이행되면 약속의 상태도 이행되며, x의 불변 값이 약속의 불변 값으로 사용됩니다.

  2.3.2.3.如果x的状态为rejected, promise的状态也为rejected, 并且以x的不可变原因作为promise的不可变原因。

2.3.4.如果x不是对象或函数,则将promise状态转换为fulfilled并且以x作为promise的不可变值。

 Promise.prototype.then()

Promise实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为Promise实例添加状态改变时的回调函数。 前面说过,then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

var promise = new Promise(function(resolve, reject) {  
    setTimeout(function() { 
        console.log("2秒后,我运行了");
        resolve('异步操作成功了');     //1
    }, 2000) 
    
})
promise.name = 'promise';
console.log('promise:',promise)var promise2 = promise.then(function (value) {
    console.log(value);
})
promise2.name = 'promise2';
console.log('promise2:',promise2);// promise://     Promise { pending }//     [[PromiseStatus]]:"pending"//     [[PromiseValue]]:undefined//     name:"promise"//     proto:Promise {constructor: , then: , catch: , …}// promise2:// Promise { pending }//     [[PromiseStatus]]:"pending"//     [[PromiseValue]]:undefined//     name:"promise2"//     proto:Promise {constructor: , then: , catch: , …}

我们可以知道promise.then()方法执行后返回的是一个新的Promise对象。也就是说上面代码中的promise2是一个Promise对象,它的实现效果和下面的代码是一样的,只不过在then()方法里,JS引擎已经自动帮我们做了。

promise2 = new Promise(function (resolve,reject) {})

既然在then()函数里已经自动帮我实现了一个promise对象,但是我要怎么才能给resolve()或reject()函数传参呢?其实在then()函数里,我们可以用return()的方式来给promise2的resolve()或reject()传参。看一个例子。

 promise =  Promise("2秒后,我运行了"'异步操作成功了');     
        
    }, 2000 promise2 = promise.then(
     (1 promise3 = promise2.then('is:''error:'= 'promise2'3000

Promise与错误状态处理

.then(null, rejection),用于指定异步操作发生错误时执行的回调函数。下面我们做一个示例。

var promise = new Promise(function(resolve, reject) {
    setTimeout(function () {
            reject('error');
    },2000);
}).then(null,function(error) {
    console.log('rejected', error)
});//rejected error

我们知道then()方法执行后返回的也是一个promise对象,因此也可以调用then()方法,但这样的话为了捕获异常信息,我们就需要为每一个then()方法绑定一个.then(null, rejection)。由于Promise对象的错误信息具有“冒泡”性质,错误会一直向后传递,直到被捕获为止。因此Promise为我们提供了一个原型上的函数Promise.prototype.catch()来让我们更方便的 捕获到异常。

我们看一个例子

var promise = new Promise(function(resolve, reject) {
    setTimeout(function () {
            reject('error');
    },2000);
}).then(function(value) {
    console.log('resolve', value);
}).catch(function (error) {
    console.log(error);
})//运行结果//error

上面代码中,一共有二个Promise对象:一个由promise产生,一个由then产生。它们之中任何一个抛出的错误,都会被最后一个catch捕获。

但是如果用.then(null, rejection)方法来处理错误信息,我们需要在每一个rejection()方法中返回上一次异常信息的状态,这样当调用的then()方法一多的时候,对会对代码的清晰性和逻辑性造成影响。

所以,一般来说,不要在then方法里面定义Reject状态的回调函数(即then的第二个参数),总是使用catch方法。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

在前端中的html基础知识 

知名的网站前端布局分析
关于前端的css基本知识

위 내용은 Promise를 시작하기 위해 알아야 할 사항의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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