在这种情况下,我如何理解 Promise all ?

How can I understand about the Promise all in this case?

我想做一个同步任务,试过类似下面的代码,这和我之前对 Promise 的想法不一样,你能为我解释一下这个吗?

var p2 = new Promise((resolve, reject) => {
  console.log('Promise 2');
  resolve();
});

var p1 = new Promise((resolve, reject) => {
  console.log('Promise 1');
  resolve();
});

Promise.all([p1]).then(p2);

总是在"Promise 1"之前输出"Promise 2"。

当你调用new Promise时,你传递给它的函数(承诺执行器)是运行立即,然后再收到承诺并将其存储在变量中。原因是 promise 执行器函数的工作是 start 一个异步进程。如果不调用它就无法启动它。这就是为什么您在 "Promise 1" 之前看到 "Promise 2",因为这是您调用 new Promise.

的顺序

另请注意,Promise.all 不会启动任何内容。它只是监视已经在进行中的过程并报告结果。

下面是 new Promise 的更实际用法,可以帮助您理解事物的时间安排:启动计时器并在计时器触发时解决承诺:

function timer(ms, value) {
    return new Promise(resolve => {
        console.log(`promise executor called for value "${value}"`);
        setTimeout(() => {
            console.log(`timer completed for value "${value}", resolving promise`);
            resolve(value);
        }, ms);
    });
}

// Note that I never do anything with the promise `timer` returns
// here, but since it's already started by the time
// it returns, it still does something
console.log("creating anonymous");
timer(800, "anonymous");

console.log("creating p1");
const p1 = timer(1600, "p1");
console.log("creating p2");
const p2 = timer(2400, "p2");
console.log("calling Promise.all([p1, p2])");
Promise.all([p1, p2])
.then(results => {
    console.log(`Promise.all promise reseolved with "${JSON.stringify(results)}"`);
})
.catch(error => {
    // Normally you'd handle errors here, it's just
    // that the promsies from `timer` are never rejected
});
.as-console-wrapper {
    max-height: 100% !important;
}

你想把那些字符串放到resolve方法里就可以了。你想要什么。实际 promise 里面的 console.logs 不是异步的。

 var p2 = new Promise((resolve, reject) => {
   resolve('Promise 2');
 });

 var p1 = new Promise((resolve, reject) => {
   resolve('Promise 1');
 });

 Promise.all([p1]).then(res1 => {
   console.log(res1);
   return p2
 }).then(res2 => console.log(res2))

Promise.all 顾名思义,用于等待您传递给它的所有承诺得到实现。

但由于您只想等待 p1 完成,只需将 .then() 添加到 p1:

var p1 = new Promise((resolve, reject) => {
   console.log('Promise 1');
   resolve('Promise 1');
 }).then()

Promise.prototype.then()方法returns一个承诺。那么为什么不简单地把你想放在 p2 中的任何东西放在你传递给 then() 的回调中,就像这样:

var p1 = new Promise((resolve, reject) => {
       console.log('Promise 1');
       resolve();
     }).then((value) => console.log('Promise 2'))

我只是想告诉你,即使你从未使用过 Promise.all.then -

,你也会有输出

const makePromise = x =>
  new Promise(r =>
    ( console.log("constructing...", x)
    , setTimeout(r, 2000, x)  // fake 2 second delay
    )
  )

const a = makePromise("a")
const b = makePromise("b")
const c = makePromise("c")

console.log("construction complete!")

// constructing... "a"
// constructing... "b"
// constructing... "c"
// construction complete!

在上面,我们构建了三 (3) 个承诺并显示了输出,即使我们从未在程序的其他任何地方使用过 abc

当我们附加 .then(handler) 时,解析值将传递给 handler -

const makePromise = x =>
  new Promise(r =>
    ( console.log("constructing...", x)
    , setTimeout(r, 2000, x)
    )
  )

const a = makePromise("a")
const b = makePromise("b")
const c = makePromise("c")

console.log("construction complete!")

// constructing... "a"
// constructing... "b"
// constructing... "c"
// construction complete!

Promise.all([a, b, c])
  .then(r => console.log("done!", r))
  .catch(e => console.error("error!", e))

// done!

这可能意味着 .then 在您的程序稍后 way 中被调用,甚至可能是异步调用 -

const makePromise = x =>
  new Promise(r =>
    ( console.log("constructing...", x)
    , setTimeout(r, 2000, x)
    )
  )

const a = makePromise("a")
const b = makePromise("b")
const c = makePromise("c")

console.log("construction complete!")

// constructing... "a"
// constructing... "b"
// constructing... "c"
// construction complete!

const main = () =>
  Promise.all([a, b, c])
    .then(r => console.log("done!", r))
    .catch(e => console.error("error!", e))

console.log("please wait 5 seconds...")
setTimeout
  ( _ =>
      ( console.log("calling main() now...")
      , main()
      )
  , 5000
  )


// calling main() now...
// done

我们写了makePromise来人为地延迟解析值两秒(在程序中是2000毫秒)。

在这个最终程序中需要注意的关键是两秒立即开始。当我们在五秒后调用 Promise.all(...).then(...) 时,我们所有的 Promise 都已经解析了一个值。这就是为什么我们在调用 main() 后立即看到 "done" 的原因。