在这种情况下,我怎么能理解Promise呢?

问题描述 投票:1回答:2

我想做一个同步任务,试了一下下面的代码,和我之前想的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"。

javascript promise es6-promise
2个回答
4
投票

当你调用 new Promise,你传递给它的函数(即 承诺执行人)是运行 马上,然后再将承诺接收回来并存储到你的变量中。这是因为承诺执行函数的工作是 开创 一个异步进程。如果它没有被调用,它就不能启动它。这就是为什么你在 "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;
}

2
投票

你要把这些字符串放到resolution方法中 然后你就会得到你想要的东西。实际承诺里面的 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))

2
投票

Promise.all 就像它的名字一样,是用来等待你传递给它的所有承诺都得到实现。

但由于你只想等待 p1 实现,只要加上 .then()p1:

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

负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: Promise.prototype.then() 方法返回一个承诺。所以为什么不干脆把你想放的东西放在 p2 的回调中,你传递给 then(),像这样。

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

1
投票

我只是想告诉你,你会有输出 即使你从来没有使用。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)个承诺,即使我们从来没有使用过,输出也会被显示出来 a, bc 在程序中的其他地方。

当我们把 .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 应约而至 途径 在你的程序中,甚至可能是异步的 ----------------------------。

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(...) 五秒钟后,我们所有的承诺都已经解决了一个值。这就是为什么我们看到 "done" 紧接着 main() 被称为。

© www.soinside.com 2019 - 2024. All rights reserved.