Javascript Promise用法详解(3)


【2】 一旦状态改变,就不会再变,任何时候都可以得到这个结果 Promise对象的状态改变,只有两种可能:从 pending 变为 fulfilled 和从 pending 变为 rejected。 只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。 如果改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。 这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

例如以下代码, reject 方法是无效的

var promise = new Promise((fuck, reject) => {
 resolve("xxxxx");
 //下面这行代码无效,因为前面 resolve 方法已经将 Promise 的状态改为 resolved 了
 reject(new Error()); 
});

promise.then((value) => { 
 console.log(value);
})

下图是 Promise 的状态处理流程图

5、Promise 的执行顺序

我们知道 Promise 在创建的时候是立即执行的,但是事实证明 Promise 只能执行异步操作,即使在创建 Promise 的时候就立即改变它状态。

var p = new Promise((resolve, reject) => {
 console.log("start Promise");
 resolve("resolved"); 
});

p.then((value) => {
 console.log(value);
}) 

console.log("end Promise");

打印的结果是:

start Promise
end Promise
resolved

或许你会问,这个操作明明是同步的,定义 Promise 里面的代码都被立即执行了,那么回调应该紧接着 resolve 函数执行,那么应该先打印 “resolved” 而不应该先打印 “end Promise”.

这个是 Promise 规范规定的,为了防止同步调用和异步调用同时存在导致的混乱

6、Promise 的链式调用(连贯操作)

前面我们讲过,Promise 的 then 方法以及 catch 方法返回的都是新的 Promise 对象,这样我们可以非常方便的解决嵌套的回调函数的问题, 也可以很方便的实现流程任务。

var p = new Promise(function(resolve, reject) {
  resolve();
});
function taskA() {
  console.log("Task A");
}
function taskB() {
  console.log("Task B");
}
function taskC() {
  console.log("Task C");
}
p.then(taskA())
.then(taskB())
.then(taskC())
.catch(function(error) {
  console.log(error);
});

上面这段代码很方便的实现了从 taskA 到 taskC 的有序执行。

当然你可以把 taskA - taskC 换成任何异步操作,如从后台获取数据:

var getJSON = function(url, param) {
 var promise = new Promise(function(resolve, reject){
 var request = require('ajax-request');
 request({url:url, data: param}, function(err, res, body) {
  if (!err && res.statusCode == 200) {
  resolve(body);
  } else {
  reject(new Error(err));
  }
 });
 });

 return promise;
};
var url = "login.php";
getJSON(url, {id:1}).then(result => {
 console.log(result);
 return getJSON(url, {id:2})
}).then(result => {
 console.log(result);
 return getJSON(url, {id:3});
}).then(result => {
 console.log(result);
}).catch(error => console.log(error));


      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/244.html