【问题标题】:How can I understand about the Promise all in this case?在这种情况下,我如何理解 Promise all?
【发布时间】:2020-05-16 00:04:22
【问题描述】:

我想做一个同步任务并尝试了类似下面的代码,这与我之前对 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


【解决方案1】:

当您调用new Promise 时,您传递给它的函数(promise 执行器)会立即运行,然后您会收到返回的承诺并将其存储在您的多变的。原因是 promise executor 函数的工作是启动一个异步进程。如果不调用它就无法启动它。这就是为什么您会在“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】:

    您想将这些字符串放入 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))
    

    【讨论】:

      【解决方案3】:

      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'))
      

      【讨论】:

        【解决方案4】:

        我只想告诉你,即使你从未使用过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) 个 promise,并显示了输出,即使我们从未在程序中的任何其他地方使用过 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 在您的程序稍后方式中被调用,甚至可能是异步调用 -

        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"

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-07-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多