JavaScript其实是一种单线程执行的语言,这个在前面一篇文章说过。传送阵
在JavaScript代码中,你经常会遇到两种异步编程风格:老派callbacks,新派promise。
回调函数而老牌的回调函数,这个上一篇文章聊过,但是这个回调函数一定是异步吗?这个可以聊一下。
异步callbacks 其实就是函数,只不过是作为参数传递给那些在后台执行的其他函数. 当那些后台运行的代码结束,就调用callbacks函数,通知你工作已经完成,或者其他有趣的事情发生了。使用callbacks 有一点老套,在一些老派但经常使用的API里面,你会经常看到这种风格。如下:
console.log('主线程1');
setTimeout(()=>{
console.log('回调函数');
})
console.log('主线程2');
这个是异步的回调函数,但是JavaScript中的回调函数不都是异步,比如如下:
console.log('主线程1');
const games=['艾尔登法环','战神4','消逝的光芒2','瘟疫传说'];
games.forEach((game,index)=>{
console.log('第'+index+'个元素',game);
});
console.log('主线程2');
所以说老牌的异步是通过回调函数实现的,但是回调函数不一定是异步。
Promise 对象用于表示一个异步 *** 作的最终完成 (或失败)及其结果值。
通过官网的的解释如果抽象的说:Promise是JS中进行异步编程的新的解决方法。首先可以看出Promise是一个对象的构造函数,而通过Promise生成的对象用来封装了一个异步 *** 作并可以获取其结果。
一个 Promise 对象代表一个在这个 promise 被创建出来时不一定已知的值。它让您能够把异步 *** 作最终的成功返回值或者失败原因和相应的处理程序关联起来。 这样使得异步方法可以像同步方法那样返回值:异步方法并不会立即返回最终的值,而是会返回一个 promise,以便在未来某个时候把值交给使用者。
一个 Promise
必然处于以下几种状态之一:
待定状态的 Promise 对象要么会通过一个值被兑现(fulfilled),要么会通过一个原因(错误)被拒绝(rejected)。当这些情况之一发生时,我们用 promise 的 then 方法排列起来的相关处理程序就会被调用。如果 promise 在一个相应的处理程序被绑定时就已经被兑现或被拒绝了,那么这个处理程序就会被调用,因此在完成异步 *** 作和绑定处理方法之间不会存在竞争状态。
看执行图如下:
因为 Promise.prototype.then
和 Promise.prototype.catch
方法返回的是 promise, 所以它们可以被链式调用。
Promise
对象是由关键字 new
及其构造函数来创建的。该构造函数会把一个叫做“处理器函数”(executor function)的函数作为它的参数。这个“处理器函数”接受两个函数——resolve
和 reject
——作为其参数。当异步任务顺利完成且返回结果值时,会调用 resolve
函数;而当异步任务失败且返回失败原因(通常是一个错误对象)时,会调用reject
函数。
格式:
new Promise(function(resolve,reject){executor函数})
构建Promise对象时,需要传入一个executor函数,主要业务流程都在executor函数中执行.Promise构造函数执行时立即调用executor函数,resolve和reject两个函数作为参数传递给executor,resolve和reject函数被调用时,分别将promise的状态改为fulfilled(完成)或者rejected(失败).一旦状态改变,就不会再变,如何时候都可以得到这个结果.在executor函数中调用resolve函数后,会触发promise.then设置的回调函数,而调用reject函数后,会触发promise.catch设置的回调函数.
补充一个then方法:
//then() 方法返回一个 Promise 。它最多需要有两个参数:Promise 的成功和失败情况的回调函数。
p.then(onFulfilled[, onRejected]);
p.then(value => {
// fulfillment
}, reason => {
// rejection
});
onFulfilled
可选
当 Promise 变成接受状态(fulfilled)时调用的函数 。该函数有一个参数,即接受的最终结果(the fulfillment value)。如果该参数不是函数,则会在内部被替换为 (x) => x
,即原样返回 promise 最终结果的函数.
onRejected
可选
当 Promise 变成拒绝状态(rejected)时调用的函数。该函数有一个参数,即拒绝的原因(rejection reason
)。 如果该参数不是函数,则会在内部被替换为一个 “Thrower” 函数 (it throws an error it received as argument)。
返回值先不说,后面具体聊,这个就是先理解一下例子中的语法,方便容易看懂。
var promise=new Promise(()=>{});
console.log('promise ',promise);
var promise1=new Promise((resolve)=>{});
console.log('promise1 ',promise1);
var promise2=new Promise((resolve,reject)=>{});
console.log('promise2 ',promise2);
可以看出如果执行函数默认的状态:pending
例子:
console.log('主线1');
// 一般习惯在执行器中的参数为:resolve,reject;
var promise=new Promise((resolve,reject)=>{
//这个函数其实一执行器,其是同步函数
console.log('执行器');
var flag=Math.random();
// 如果随机小数大于0.5就是成功
if(flag>0.5){
resolve('成功');
}else{
reject('失败');
}
}
);
console.log(promise);
// 通过then方法调用异步的 *** 作:
// 这样写可能会更加好立即,但是这个两个参数方法都应该是匿名函数
// promise.then(function onresolve(value){},function onrejected(reason){});
promise.then((value)=>{
console.log(value);
},(reason)=>{
console.log(reason);
})
console.log('主线2');
其实可以看出Promise中的执行器也是一个同步函数。
首先说明怎样使用 Promise,创建 Promise。但是看上面的似乎本质上 Promise 是一个函数返回的对象, 可以在它上面绑定回调函数,这样就不需要在一开始把回调函数作为参数传入这个函数了。
为什么这样说呢?因为老牌实现回调函数,就是把回调函数作为参数传递给调用的函数,来举一个例子。
官网的例子如下:
假设现在有一个名为 createAudioFileAsync()
的函数,它接收一些配置和两个回调函数,然后异步地生成音频文件。一个回调函数在文件成功创建时被调用,另一个则在出现异常时被调用。
// 成功的回调函数
function successCallback(result) {
console.log("音频文件创建成功: " + result);
}
// 失败的回调函数
function failureCallback(error) {
console.log("音频文件创建失败: " + error);
}
// 这个可以看出在在调用这个函数是为了执行audioSettings 生成一个音频文件,但是成功就调用successCallback,失败就调用failureCallback。
// 所以将两个根据成功失败分别调用的回调函数作为参数传递给了这个createAudioFileAsync方法
createAudioFileAsync(audioSettings, successCallback, failureCallback)
当然上面例子是一个伪代码,不能执行,只是简单的体现了这个意思。
现在来一个可运行的例子:
第一个:不写回调函数,着急会报错。这个好立即
function test(callback_sucess,callback_fail) {
setTimeout(()=>{
var flag=Math.random();
// 如果随机小数大于0.5就是成功
if(flag>0.5){
callback_sucess('成功');
}else{
callback_fail('失败');
}
},0);
}
test(callback_sucess,callback_fail);
会直接报错。
第二种:如果延迟创建回调函数呢?
setTimeout(()=>{
window.callback_sucess=function (value) {
console.log("异步执行",value);
};
window.callback_fail=function (reason) {
console.log("异步执行",reason);
};
},5000);
function test(fun,callback_sucess,callback_fail) {
setTimeout(()=>{
var flag=Math.random();
// 如果随机小数大于0.5就是成功
if(flag>0.5){
callback_sucess('成功');
}else{
callback_fail('失败');
}
},0);
}
test( callback_sucess,callback_fail);
也会报错,当然这个演示只能说是方面演示这个过程而已,当然异步的回调不会这样简单。但是可以看出一点那就是回调函数再作为参数传递的时候,就需要将回调函数写好,不然会报错。
更现代的函数会返回一个 Promise 对象,使得你可以将你的回调函数绑定在该 Promise 上。
如果函数 createAudioFileAsync()
被重写为返回 Promise 的形式,那么我们可以像下面这样简单地调用它:
// 可以看出通过promise先调用目的执行audioSettings 生成一个音频文件 内部会绑定成功与失败两个回调函数。但是不调用,只是简单绑定
const promise = createAudioFileAsync(audioSettings);
//然后通过then调用回调函数
promise.then(successCallback, failureCallback);
可以看出回调函数的调用,还有回调函数的绑定时分开的。所以也就可以
代码演示:
var promise=new Promise((resolve,reject)=>{
console.log("executor函数");
setTimeout(()=>{
var flag=Math.random();
// 如果随机小数大于0.5就是成功
if(flag>0.5){
resolve('成功');
}else{
reject('失败');
}
},0);
});
console.log('Promise创建好了')
setTimeout(()=>{
promise.then(
value =>{
console.log(value);
},reason=>{
console.log(reason);
})
},2000);
可以看出回调的函数,哪怕是后面再写好也是可以运行,这个和传统的回调函数的区别就有了。其实如果单独看Promise和回调函数的话,会发现其实和异步的关系,只能说是在处理器函数其实也就等同于同步函数,其处理函数中包含的异步后,而Promise本身回调函数的异步(微任务)却是再通过调用方法进行触发的(then)。这个可以看出调用回调函数的灵活性。
当然如果不再then方法外没有定时器,其实then这个promise回调函数要比异步的 *** 作更早的,这个涉及到两个概念 微任务和宏任务。这个前面聊过,这里不再陈述。传送阵
回调地狱要想做多重的异步 *** 作,会导致经典的回调地狱,这个就是传统的调用函数带来的问题:
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ' + finalResult);
}, failureCallback);
}, failureCallback);
}, failureCallback);
上面是一个官网的伪代码,但是拆开会更具方便理解上面写的是什么:
// 将例子拆解看一下
doSomething(function(result) { 传递一个参数result }, failureCallback);
//通过传递参数result,然后通过异步 *** 作成功得到一个newResult,然后调用这个方法newResult作为参数
doSomethingElse(result, function(newResult) { }, failureCallback);
//通过传递参数newResult,然后通过异步 *** 作成功得到一个finalResult,然后调用这个方法finalResult作为参数
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ' + finalResult);
}, failureCallback);
回调地狱的官方理解上说的是函数作为参数层层嵌套看起来很好理解,回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调函数的执行条件。这样第一不方便阅读,第二不方便异常处理,毕竟说实话套上几层不费时间捋一下谁都懵。
如果支持链式调用的话:promise比如通过then
返回 也是一个promise,所以说可以链式调用。可以把回调绑定到返回的 Promise 上,形成一个 Promise 链:
doSomething().then(function(result) {
return doSomethingElse(result);
})
.then(function(newResult) {
return doThirdThing(newResult);
})
.then(function(finalResult) {
console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);
这样写是否阅读起来更具方法,让人更具方便理解。
当然程序缩写的算法前提是支持链式调用,才可以通过解决回调地狱这个问题。
虽然解决方法是可以通过Pormise解决的,这个也是本篇聊这个对象的原因。但是有一点要补充,虽然promise已经很牛逼了,其不是最终解决的方法,因为还有async/await.
这个也会聊(又tm一个坑,后面陆续填上)。
所以看出promise的两个特点:
promise 回调函数方式更具灵活。 老牌:回调必须在异步任务前指定。promise:启动异步任务返回一个promise对象,然后再给promise绑定回调函数,甚至可以再异步任务结束后指定。 支持链式调用,可以解决回调地狱问题。 pormise 的api现在看是搞一下官网中的一些方法。
构造函数其实这个前面为了方便例子所以在前面说过了,此处为了整体的可读性,这里再重复写一遍。
Promise
对象是由关键字 new
及其构造函数来创建的。该构造函数会把一个叫做“处理器函数”(executor function)的函数作为它的参数。这个“处理器函数”接受两个函数——resolve
和 reject
——作为其参数。当异步任务顺利完成且返回结果值时,会调用 resolve
函数;而当异步任务失败且返回失败原因(通常是一个错误对象)时,会调用reject
函数。
格式:
new Promise(function(resolve,reject){executor函数})
构建Promise对象时,需要传入一个executor函数,主要业务流程都在executor函数中执行.Promise构造函数执行时立即调用executor函数,resolve和reject两个函数作为参数传递给executor,resolve和reject函数被调用时,分别将promise的状态改为fulfilled(完成)或者rejected(失败).一旦状态改变,就不会再变,如何时候都可以得到这个结果.在executor函数中调用resolve函数后,会触发promise.then设置的回调函数,而调用reject函数后,会触发promise.catch设置的回调函数.
还是那个例子:
var promise=new Promise((resolve,reject)=>{
console.log("executor函数");
setTimeout(()=>{
var flag=Math.random();
// 如果随机小数大于0.5就是成功
if(flag>0.5){
resolve('成功');
}else{
reject('失败');
}
},0);
});
如果判断成功如下:
如果是失败如下:
可以看出根据自己异步Math.random()返回的值于0.5进行判断大小,而决定两个不同的状态。
当然还有构造函数方法,直接可以创建成功或者失败状态的Promise,这个后面可以聊,现在简单的演示一下。
var promise1=Promise.resolve(1);
var promise2=Promise.reject(0);
Promose的状态
其实上面的例子可以看出Promise回更具自己的条件进行判断其状态,如上面构建函数的例子如下图:
当然如果创建一个Promise’实例对象然后没有具体逻辑执行来判断是否成功失败,那么其状态如下:
const promise=new Promise((resolve,reject)=>{});
一般说是成功或失败的状态,当然还有一个初始化的状态了。但是还有一种状态也会也会影响初始化promise的状态。
const promise_err=new Promise((resolve,reject)=>{
console.log('线程');
throw new Error('报错了');
});
console.log(promise_err);
promise_err.then((value)=>{
console.log('promise_errd的状态成功:'+value);
},(reason)=>{
console.log('promise_errd的状态错误状态:'+reason);
})
可以抛出的异常也会将Promise的状态pending状态变成了rejected,可以也是一个调用错误回调函数。
然后再来一个大胆的向反,既然抛出的错误,所以使用了reject这个回调函数,其参数是一个Error,那如果抛出一个其它的数据呢?
比如:
const promise_num=new Promise((resolve,reject)=>{
console.log('线程');
throw 11111111;
});
console.log(promise_num);
promise_num.then((value)=>{
console.log('promise_num 的状态成功:'+value);
},(reason)=>{
console.log('promise_num 的状态错误状态:'+reason);
})
方法
promise上的方法其实分两种一个是构造函数对象上的方法,一个是实例对象上的方法。看一下官网截图
可以看到构造函数上的方法方法,需要构造函数对象进行调用。而Promise.prototype上的原型方法其实通过new的对象可以调用,这个为什么可以调用,如果不了解的话,而已看一下前面的原型和原型链文章。
Promise.prototype.then() : 对应构造函数 (resolve,reject)=>{}。then方法中的参数回调函数 第一个回调函数(对应resolve):成功的回调函数:(value)=>{}第二个回调函数(对应reject)(可选): 失败的回调函数:(reason)=>{}返回值:指定用于得到成功或者失败而选择调用那个回调函数,然后返回一个promise对象。 Promise.prototype.catch() 这个之有一个参数; 因为这个方法只能调用失败的回调函数:(reason)=>{} 。这个方法相当于Promise.prototype.then(undefined,(reason)=>{} )返回值:指定用于得到 失败调用回调函数,然后返回一个promise对象。 Promise.resolve(value)方法: value 可以说成功的数据胡总和是promise对象返回值:一个成功或者失败的promise对象,如果参数value是一个promise,就返回这个参数promise就直接返回。 Promise.reject(reason)方法: reason: 失败的原因。返回值:一个失败的promise对象。 Promise.all (promises)方法: promises:是一个promise数组。返回一个promise,当然这个参数都可以成功执行返回一个成功状态的promise对象,只要一个是错误的那返回一个错误的promise对象。 Promise.race(promises)方法 promises:是一个promise数组。返回一个promise,但是其是成功还是失败都是根据promises数组中的第一个异步执行成功或失败的状态为最终状态。 实例对象方法这个可以说是构造函数原型对象上的方法,可以通过实例对象调用。
Promise.prototype.then()在创建Promise对象的时候,其执行不是异步(当然对象里面可以房异步方法),而通过then调用的才是异步(微任务)。测试:
console.log('主线程开始');
const promise1 = new Promise((resolve, reject) => {
console.log('主线程1');
resolve('成功!');
console.log('主线程2');
});
promise1.then((value) => {
console.log('第一个参数打印',value); //
});
console.log('主线程结束');
then() 方法返回一个 Promise 。它最多需要有两个参数:Promise 的成功和失败情况的回调函数。
//then() 方法返回一个 Promise 。它最多需要有两个参数:Promise 的成功和失败情况的回调函数。
p.then(onFulfilled[, onRejected]);
p.then(value => {
// fulfillment
}, reason => {
// rejection
});
onFulfilled
可选
当 Promise 变成接受状态(fulfilled)时调用的函数 。该函数有一个参数,即接受的最终结果(the fulfillment value)。如果该参数不是函数,则会在内部被替换为 (x) => x
,即原样返回 promise 最终结果的函数.
onRejected
可选
当 Promise 变成拒绝状态(rejected)时调用的函数。该函数有一个参数,即拒绝的原因(rejection reason
)。 如果该参数不是函数,则会在内部被替换为一个 “Thrower” 函数 (it throws an error it received as argument)。
当一个 Promise 完成(fulfilled)或者失败(rejected)时,返回函数将被异步调用(由当前的线程循环来调度完成)
演示:
// 第一个promise1
const promise1 = new Promise((resolve, reject) => {
resolve('成功!');
});
console.log('promise1',promise1);
promise1.then((value) => {
console.log('第一个参数打印',value); //
});
可以看出new Promise((resolve, reject)中的两个参数方法,是通过then调用的时候传递的两个实参。因为习惯这两个参数resolve和reject。这两个名字可以随便写的如下:
const promise1 = new Promise((a, b) => {
a('成功!');
});
console.log('promise1',promise1);
promise1.then((value) => {
console.log('第一个参数打印',value); //
},(reason)=>{
console.log('第二个参数打印',reason);
});
链式 *** 作的注意事项
then 返回一个promise对象的,所以也就意味着可以链式 *** 作。
这个返回的promis其实又有一些要求,看一下官网所言:
不过可以总结为:
如果抛出异常,新的promise变成rejected的状态,reason为抛出的异常。如果返回时非promise的任意值,新的promise变为resolved,value为返回值。如果返回一个新promise,此promise的结果就会成为新promise的结果。还是老规矩演示:
var promise=new Promise((resolve,reject)=>{
// 这里的估计写调用错误状态
reject(1);
});
var return_promise= promise.then(undefined,(reason)=>{
console.log('失败------',reason)
});
console.log(return_promise);
// 为更方便所以将整个promise.then(....).then();分成两部分
return_promise.then((value)=>{console.log('成功-----',value)})
可以看出then 默认返回一个promise,但是变成中可以通过自己return阻断默认的返回,当然也可以自己写一个全新的promise对象。
var promise=new Promise((resolve,reject)=>{
reject(1);
});
var return_promise= promise.then(undefined,(reason)=>{
throw 3; // 这里返回一个状态错误的promise
});
console.log(return_promise);
如果返回的是值:
var promise=new Promise((resolve,reject)=>{
reject(1);
});
var return_promise= promise.then(undefined,(reason)=>{
return 3; // 这里返回一个状态成功的promise
});
console.log(return_promise);
有一个大胆的想法,看如下代码:
var promise=new Promise((resolve,reject)=>{
reject(1);
});
console.log('11111111111111111');
var return_promise= promise.then((value)=>{
console.log('成功')
}
// 其实这样写 省略了等于如下写:
// ,reason=>{
// throw reason;
//}
);
console.log(return_promise);
看结果:
但是现在来一个大胆的想法,让then中运行一个异步方式。看看是什么鬼:
var promise=new Promise((resolve,reject)=>{
reject(1);
});
console.log('11111111111111111');
var return_promise= promise.then(undefined,(reason)=>{
console.log('66666666666666')
setTimeout(()=>{
console.log('失败------',reason)
resolve(30);
},2000);
});
console.log(return_promise);
return_promise.then((value)=>{console.log('成功-----',value)})
可以看出then中如果写要给异步的执行resolve或者reject方法,以及返回任何数据,包括异步中返回promise(当然抛出错误也一样),然后通过其返回then方法可以结果是一样:结果是undefined,如果非要返回整个带有异步 *** 作的结果,那就需要封装成要给新的promise,将异步写入整个promise对象中。
如下:
var promise=new Promise((resolve,reject)=>{
reject(1);
});
console.log('11111111111111111');
var return_promise= promise.then(undefined,(reason)=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('失败------',reason)
resolve(30);
},2000);
});
});
所以可以说无论then方法的中可以调用异步 *** 作,但是一般在链式的时候会封装在一个新promise中,不会直接写入,不然后面的的链式就没有意义。
打断链式 *** 作那么链式 *** 作是否可以打断?可以那就是在执政then *** 作的时候返回一个pending状态的promise就可以了。
var promise=new Promise((resolve,reject)=>{
resolve(1);
});
var return_promise= promise.then((value)=>{
console.log(value)
return new Promise(()=>{});
});
console.log(return_promise)
return_promise.then((value)=>{
console.log('测试成功',value)
},reason => {
console.log('测试失败',reason)
})
可以看出状态成pending自然也就不会在继续链式调用了。
Promise.prototype.catch() 就不在演示了,其就是Promise.prototype.then(undefined, reason=>{}),所以不再继续演示。
Promise.prototype.finally()finally() 方法返回一个Promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。
这避免了同样的语句需要在then()和catch()中各写一次的情况。
格式:
p.finally(function() {
// 返回状态为(resolved 或 rejected)
});
finally()
虽然与 .then(onFinally, onFinally)
类似,它们不同的是:
来一个神奇的例子:
//Promise.resolve 返回一个成功状态的promsie 而Promise.reject返回要给失败的promsie后面具体聊
Promise.resolve(2).then(() => {}, () => {});
Promise.resolve(2).finally(() => {});
Promise.reject(3).then(() => {}, () => {});
Promise.reject(3).finally(() => {});
Promise 构造对象上的方法(静态方法)
Promise.resolve()
Promise.resolve(value)方法返回一个以给定值解析后的Promise 对象。如果这个值是一个 promise ,那么将返回这个 promise ;如果这个值是thenable(即带有"then" 方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态;否则返回的promise将以此值完成。此函数将类promise对象的多层嵌套展平。
警告:不要在解析为自身的thenable 上调用Promise.resolve。这将导致无限递归,因为它试图展平无限嵌套的promise。
格式:
Promise.resolve(value);
参数 value
将被Promise对象解析的参数,也可以是一个Promise对象,或者是一个thenable。
返回值
返回一个带着给定值解析过的Promise对象,如果参数本身就是一个Promise对象,则直接返回这个Promise对象。
var p1=Promise.resolve(2);
var p2=Promise.resolve(
new Promise((resolve,reject)=>{
reject(1);
})
);
可以看出resolve本身应该执行一个成功,但是如果参数是一个promise就直接按照这个参数pomise而直接返回。
Promise.reject()**Promise.reject()**方法返回一个带有拒绝原因的Promise
对象。
格式如下:
Promise.reject(reason);
这个如果参数是Promise,不会影响这个错误状态的。
var p1=Promise.reject(2);
var p2=Promise.reject(
new Promise((resolve,reject)=>{
resolve(1);
})
);
Promise.all()
Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,并且只返回一个Promise实例, 那个输入的所有promise的resolve回调的结果是一个数组。这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。它的reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。
语法格式:
Promise.all(iterable);
参数 iterable一个可迭代对象,如 Array 或 String。返回值 如果传入的参数是一个空的可迭代对象,则返回一个已完成(already resolved)状态的 Promise。如果传入的参数不包含任何 promise,则返回一个异步完成(asynchronously resolved) Promise。注意:Google Chrome 58 在这种情况下返回一个已完成(already resolved)状态的 Promise。其它情况下返回一个处理中(pending)的Promise。这个返回的 promise 之后会在所有的 promise 都完成或有一个 promise 失败时异步地变为完成或失败。 见下方关于“Promise.all 的异步或同步”示例。返回值将会按照参数内的 promise 顺序排列,而不是由调用 promise 的完成顺序决定。
例子:
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
setTimeout(()=>{
resolve('foo');
}, 100);
});
Promise.all([p1, p2, p3]).then(values => {
console.log(values); // [3, 1337, "foo"]
});
其它的方式就不在具体演示,可以翻看一下官网。当然理解这些是为了下一个 *** 作而准备,那就是自己手写一个promise,这个后面有时间会写一个。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)