Javascript 试图定义一个承诺
我试图通过创建本书练习中的Promise.all方法来理解承诺是如何工作的: 我尝试使用循环遍历作为方法本身参数提供的整个数组。然后,对于成功的承诺,处理程序主体将结果推送到我之前在循环外部定义的绑定,对于被拒绝的承诺,我使用。catch的方式是将被拒绝的值作为“原因”拒绝了主要的承诺,给了它一个错误Javascript 试图定义一个承诺,javascript,promise,es6-promise,Javascript,Promise,Es6 Promise,我试图通过创建本书练习中的Promise.all方法来理解承诺是如何工作的: 我尝试使用循环遍历作为方法本身参数提供的整个数组。然后,对于成功的承诺,处理程序主体将结果推送到我之前在循环外部定义的绑定,对于被拒绝的承诺,我使用。catch的方式是将被拒绝的值作为“原因”拒绝了主要的承诺,给了它一个错误 function Promise_all(promises) { return new Promise((resolve, reject) => { if(promises.l
function Promise_all(promises) {
return new Promise((resolve, reject) => {
if(promises.length == 0) resolve(promises);
let fullArray = [];
for(let i=0; i<promises.length ; i++){
promises[i]
.then(x => fullArray.push(x))
.catch(reason => reject(new Error(reason)));
}
resolve(fullArray);
});
}
正如@Bergi所说,代码的问题在于,.then“和.catch”回调是异步调用的,因此,在调用“resolve()”时甚至没有填充“fullArray”,即使它在循环之外也是如此。为了解决这个问题,我简单地在最后完成的承诺中添加了“resolve()”,为此,我简单地添加了一个“counter”绑定,该绑定的值等于“promises”数组的长度,并且每次减少1。然后对承诺调用“resolve()”,当这个“counter”等于0时,它调用“resolve()” 但这只解决了用承诺填充“fullArray”的问题,而不是那些承诺按调用顺序正确排序的问题,为了解决这个问题,我只是用循环的“i”绑定在数组中枚举它们,最终结果如下:
function Promise_all(promises) {
return new Promise((resolve, reject) => {
if(promises.length == 0) resolve(promises);
let fullArray = [],
counter = promises.length;
for(let i=0; i< promises.length ; i++){
promises[i]
.then(x => {
fullArray[i] = x;
counter--;
if(counter == 0) resolve(fullArray)})
.catch(reason => reject(new Error(reason)));
}
});
}
功能承诺\u所有(承诺){
返回新承诺((解决、拒绝)=>{
如果(promissions.length==0)解析(promissions);
设fullArray=[],
计数器=长度;
for(设i=0;i<0.length;i++){
承诺[i]
.然后(x=>{
全数组[i]=x;
计数器--;
如果(计数器==0)解析(fullArray)})
.catch(原因=>拒绝(新错误(原因));
}
});
}
“解决承诺”-听起来你不清楚承诺会发生什么。你不能从外部“解决”或“强迫”它。承诺会自行解决,你所能做的就是倾听它。当承诺实际解决时,then
和catch
回调将始终异步调用。当您在循环之后立即调用resolve()
时,您的fullArray
实际上并没有被填充,因为循环只附加了处理程序,而没有等待任何操作。因此,如果我在数组中调用“resolve()”。那么“Promises”数组的最后一个promise中的“then”,则在“fullArray”被填充之前循环不会完成,对吗?是的,这是正确的想法。但不是数组中最后一个承诺的then
回调,而是对最后发生的任何承诺的then
回调。数组中的承诺可能在不同的时间实现,您希望等待所有承诺都实现。您需要一个计数器。还需要将promises[i]更改为Promise.resolve(promises[i])。然后()
以防在数组中传递不可接受的值(这是允许的)。我还建议使用fullArray
而不是传递的promises
数组来解析空值。
function Promise_all(promises) {
return new Promise((resolve, reject) => {
if(promises.length == 0) resolve(promises);
let fullArray = [],
counter = promises.length;
for(let i=0; i< promises.length ; i++){
promises[i]
.then(x => {
fullArray[i] = x;
counter--;
if(counter == 0) resolve(fullArray)})
.catch(reason => reject(new Error(reason)));
}
});
}