promise内部实现原理,promise三种状态和执行原理

http://www.itjxue.com  2023-01-06 18:08  来源:未知  点击次数: 

前端的Promise是干啥的?

Promise是异步编程的一种解决方案,可以替代传统的解决方案--回调函数和事件。ES6统一了用法,并原生提供了Promise对象。作为对象,Promise有以下两个特点:

(1)对象的状态不受外界影响。

(2)一旦状态改变了就不会在变,也就是说任何时候Promise都只有一种状态。

可以通过Promise的构造函数创建Promise对象。

var?promise?=?new?Promise(function(resolve,reject)setTimeout(function(){??????????????????????????????

??console.log("hello?world");},2000);

});

Promise构造函数接收一个函数作为参数,该函数的两个参数是resolve,reject,它们由JavaScript引擎提供。其中resolve函数的作用是当Promise对象转移到成功,调用resolve并将操作结果作为其参数传递出去;reject函数的作用是单Promise对象的状态变为失败时,将操作报出的错误作为其参数传递出去。如下面的代码:

???function?greet(){????var?promise?=?new?Promise(function(resolve,reject){????????var?greet?=?"hello??world";

????????resolve(greet);

????});????return?promise;

????}

????greet().then(v={????console.log(v);//*

????})

上面的*行的输出结果就是greet的值,也就是resolve()传递出来的参数。

注意:创建一个Promise对象会立即执行里面的代码,所以为了更好的控制代码的运行时刻,可以将其包含在一个函数中,并将这个Promise作为函数的返回值。

Promise的then方法

??promise的then方法带有以下三个参数:成功回调,失败回调,前进回调,一般情况下只需要实现第一个,后面是可选的。Promise中最为重要的是状态,通过then的状态传递可以实现回调函数链式操作的实现。先执行以下代码:

function?greet(){var?promise?=?new?Promise(function(resolve,reject){????var?greet?=?"hello??world";

????resolve(greet);

});return?promise;

}var?p?=?greet().then(v={console.log(v);

})console.log(p);

Promise简书

promise是什么?

1、主要用于异步计算

2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果

3、可以在对象之间传递和操作promise,帮助我们处理队列

为什么会有promise?

为了避免界面冻结(任务)

同步:假设你去了一家饭店,找个位置,叫来服务员,这个时候服务员对你说,对不起我是“同步”服务员,我要服务完这张桌子才能招呼你。那桌客人明明已经吃上了,你只是想要个菜单,这么小的动作,服务员却要你等到别人的一个大动作完成之后,才能再来招呼你,这个便是同步的问题:也就是“顺序交付的工作1234,必须按照1234的顺序完成”。

异步:则是将耗时很长的A交付的工作交给系统之后,就去继续做B交付的工作,。等到系统完成了前面的工作之后,再通过回调或者事件,继续做A剩下的工作。

AB工作的完成顺序,和交付他们的时间顺序无关,所以叫“异步”。

resolve作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;

reject作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

1、pending[待定]初始状态

2、fulfilled[实现]操作成功

3、rejected[被否决]操作失败

当promise状态发生改变,就会触发then()里的响应函数处理后续步骤;

promise状态一经改变,不会再变。

Promise对象的状态改变,只有两种可能:

从pending变为fulfilled

从pending变为rejected。

这两种情况只要发生,状态就凝固了,不会再变了

1.Promise.all() 批量执行

Promise.all([p1, p2, p3])用于将多个promise实例,包装成一个新的Promise实例,返回的实例就是普通的promise

它接收一个数组作为参数

数组里可以是Promise对象,也可以是别的值,只有Promise会等待状态改变

当所有的子Promise都完成,该Promise完成,返回值是全部值得数组

有任何一个失败,该Promise失败,返回值是第一个失败的子Promise结果

常见用法:

异步操作和定时器放在一起,,如果定时器先触发,就认为超时,告知用户;

例如我们要从远程的服务家在资源如果5000ms还没有加载过来我们就告知用户加载失败

2.Promise.race()

与 Promise.all 类似,但只等待第一个 settled 的 promise 并获取其结果(或 error)。

3.Promise.allSettled()

等待所有的 promise 都被 settle,无论结果如何。结果数组具有:

4.Promise.resolve()

Promise.resolve(value) 用结果 value 创建一个 resolved 的 promise。

5.Promise.reject()

Promise.reject(value) 用结果 value 创建一个 rejected 的 promise。

现实中的用法

回调包装成Promise,他有两个显而易见的好处:

1、可读性好

2、返回 的结果可以加入任何Promise队列

原文地址:

可参考:

promise的三种状态

promise的三种状态

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

Promise对象有以下两个特点。

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

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

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

如果某些事件不断地反复发生,一般来说,使用 Stream 模式是比部署Promise更好的选择。

如何用Promise控制for循环的异步流程

一.定义

promise是对异步编程的一种抽象。它是一个代理对象,代表一个必须进行异步处理的函数返回的值或抛出的异常。也就是说promise对象代表了一个异步操作,可以将异步对象和回调函数脱离开来,通过then方法在这个异步操作上面绑定回调函数。

遵循的是commonJS promise/A+规范。

1.状态

promise有3种状态:pending(待解决,这也是初始化状态),fulfilled(完成),rejected(拒绝)。

2.接口

promise唯一接口then方法,它需要2个参数,分别是resolveHandler和rejectedHandler。并且返回一个promise对象来支持链式调用。

promise的构造函数接受一个函数参数,参数形式是固定的异步任务,举一个栗子:

function sendXHR(resolve, reject){

var xhr = new XMLHttpRequest();

xhr.open('get', 'QueryUser', true);

xhr.onload = function(){

if((xhr.status = 200 xhr.status 300) || xhr.status === 304){

resolve(xhr.responseText);

}else{

reject(new Error(xhr.statusText));

}

};

xhr.onerror = function(){

reject(new Error(xhr.statusText));

}

xhr.send(null)

}

二.实现

要实现promise对象,首先要考虑几个问题:

1.promise构造函数中要实现异步对象状态和回调函数的剥离,并且分离之后能够还能使回调函数正常执行

2.如何实现链式调用并且管理状态

首先是构造函数:

//全局宏定义

var PENDING = 0;

var FULFILLED = 1;

var REJECTED = 2;

//Promise构造函数

function Promise(fn){

var self = this;

self.state = PENDING;//初始化状态

self.value = null;//存储异步结果的对象变量

self.handlers = [];//存储回调函数,这里没保存失败回调函数,因为这是一个dome

//异步任务成功后处理,这不是回调函数

function fulfill(result){

if(self.state === PENDING){

self.state = FULFILLED;

self.value = result;

for(var i=0;iself.handlers.length;i++){

self.handlers[i](result);

}

}

}

//异步任务失败后的处理,

function reject(err){

if(self.state === PENDING){

self.state = REJECTED;

self.value = err;

}

}

fnfn(fulfill,reject);

};

构造函数接受一个异步函数,并且执行这个异步函数,修改promise对象的状态和结果。

回调函数方法then:

//使用then方法添加回调函数,把这次回调函数return的结果当做return的promise的resolve的参数

Promise.prototype.then = function(onResolved, onRejected){

var self = this;

return new Promise(function(resolve, reject){

var onResolvedFade = function(val){

var ret = onResolved?onResolved(val):val;//这一步主要是then方法中传入的成功回调函数通过return来进行链式传递结果参数

if(Promise.isPromise(ret)){//回调函数返回值也是promise的时候

ret.then(function(val){

resolve(val);

});

}

else{

resolve(ret);

}

};

var onRejectedFade = function(val){

var ret = onRejected?onRejected(val):val;

reject(ret);

};

self.handlers.push(onResolvedFade);

if(self._status === FULFILLED){

onResolvedFade(self._value);

}

if(self._status === REJECTED){

onRejectedFade(self._value);

}

});

}

测试代码:

function async(value){

var pms = new Promise(function(resolve, reject){

setTimeout(function(){

resolve(value);;

}, 1000);

});

return pms;

}

async(1).then(function(result){

console.log('the result is ',result);//the result is 2

return result;

}).then(function(result){

console.log(++result);//2

});

(责任编辑:IT教学网)

更多

推荐linux服务器文章