Javascript 需要帮助理解Promise.all和async

Javascript 需要帮助理解Promise.all和async,javascript,node.js,promise,Javascript,Node.js,Promise,这就是我要说的代码 view: async (req, res, next) => { let formato = req.query.formato || 'details'; try { let mode = Client.getMode(formato); let options = { columns: mode.columns, w

这就是我要说的代码

view: async (req, res, next) => {  
        let formato = req.query.formato || 'details';
        try {
            let mode = Client.getMode(formato);

            let options = {
                columns: mode.columns,
                withRelated: mode.withRelated,
            };
            let client_promises = [ ]

            req.query['ids'].map( id => {

                let client =  Client.findById(id, options);
                client_promises.push(client)

            })

            let response = await Promise.all(cliente_promesas)

            return res.json({ success: true, data: response });
        } catch (error) {
            return next(error);
        }
    },
据我所知,
.map
函数迭代一个ID数组,然后将其传递给
Client.findById
,这样它就可以返回一个要实现的承诺,在解析时获取客户端的数据

现在,这些承诺被推送到一个数组,然后被传递到
Promise.all
,但我真的不明白它们在哪里得到解决。不是
Promise.all
只是在数组中的所有承诺都已解决时传递一个已解决的承诺吗

我也明白,
wait
只是让代码在继续之前等待承诺的解决。 但是,
客户承诺
中的承诺在哪里得到解决?
我知道这是最基本的,但就我的一生而言,我似乎无法阅读足够的手册和指南来理解这一点。

所有的
承诺。
所做的就是等待传递给它的数组中的每个承诺都完成。它不会“解雇”他们。事实上,传递的数组中的每个承诺甚至可能都处于已解析状态。这些承诺从一开始就“炙手可热”

例如,按id获取项目的函数立即启动,并同步返回一个承诺,该承诺最终将解析为按id检索的任何对象。这是关键:承诺的返回不是异步部分,而是解析

承诺。所有的
使所有的承诺成为一个大的
承诺

考虑下面的例子。我获取3个ID并执行您所做的操作,我调用
findById
并将函数返回的内容(承诺)放入数组,
promises
。在
findById
中,我还添加了一个额外的
。然后
调用来演示这些承诺是如何“热门”的,而不是等待
Promise调用。所有这些
。还要注意,我仍然返回
p

当我们真正到达
承诺时。所有
承诺中的所有承诺实际上都已解决,这就是为什么您看到它们首先打印到控制台。所有这些问题都需要100-600毫秒才能解决,但我们主动等待了整整1000毫秒,然后才调用
Promise.all

不幸的是(某种程度上)没有API来揭示使用本机实现的承诺的状态。我认为以前有一些用户登录库的方法,比如Bluebird和jQuery,但不包括浏览器的方式。否则,我们可以在调用
Promise.all
之前检查Promise,看看它们是否已解决或挂起

/**
*在解析之前等待一段时间的实用程序函数
*@param{number}[delay=100]等待多长时间
*@返回{Promise}延迟后将解决的承诺
*/
功能超时(延迟=100){
返回新承诺(解决=>{
设置超时(解析、延迟);
});
}
/**
*模拟返回对象的find函数
*@param{number}id要获取的对象的id
*@返回{Promise}假DB对象
*/
异步函数findById(id){
等待超时((Math.random()*500)+100);
返回{
身份证件
数据:`foo-${id}`
};
}
(异步函数(){
常量idsToGet=[1,2,3];
const promises=idsToGet.map(id=>{
//调用以获取对象
常数p=findById(id);
//让我们在这里添加另一个侦听器,以了解它们何时完成
p、 然后(r=>{
log(`${r.id}已完成`);
});
//仍然返回findById创建的实际承诺
返回p;
});
//只是为了好玩
等待超时(1000);
//等待一切完成
const res=等待承诺。全部(承诺);
log(JSON.stringify(res,null,4));
}());Promise.all()接受未解析承诺的列表/数组。
它有点像一个巨大的承诺,它接受所有未解决的承诺,直到所有承诺都得到解决,承诺。all()是未解决的

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then(function(values) {
  console.log(values);
});
在上面的示例中,您可以看到我们将3个承诺传递给Promise.all() 当所有这些都满足时,只有。然后将触发

就你而言:

 Client.findById(id, options);
必须返回一个promise对象,您正在将该对象推送到client\u promises数组中。 然后把它们喂给Promise.all(),直到现在,你的承诺只是承诺,它们还没有解决

承诺。所有人都会回报一个承诺,正如你所说,等待在它前面。
它将等待他们中的一个重新解决,并给你一系列已解决的承诺

当您执行
let client=client.findById(id,options)时,承诺实际上被“触发”(即代码开始运行)<代码>等待承诺。所有人
然后等待,直到所有人都得到解决,或者其中一人被拒绝,在这种情况下,承诺。所有人也都会拒绝第一次拒绝承诺的价值。

很可能
客户。findById
解决承诺。
承诺。所有人([promise1,promise2,promise3])
将自动启动所有三个承诺,等待所有问题得到解决(无论顺序如何),然后返回一个“ok done”(确定完成)信号,您正在等待该信号。但看起来你已经明白了这一点,所以我不确定你被困在哪里了?@JeremyThille so``承诺。所有的``履行承诺?我理解它只是等待它们被解析(由另一段代码)。“``Promise.all``是否也执行它们,如果它们已解决,则发送已解决的承诺?谢谢你是的,我就是这样理解的thing@JeremyThille你说它们已经热了是什么意思?哦,我明白了。为什么我在编写控制台
客户端时会得到
{iscompleted:false,isRejected:false,fulfillmentValue:undefined,rejectionReason:undefined}
?是不是因为代码的异步性,他们还没有解析,而我只是在代码前面放置一个wait时才看到它们被解析