【问题标题】:JavaScript and Promise.all()JavaScript 和 Promise.all()
【发布时间】:2018-05-03 03:26:41
【问题描述】:

我正在尝试使用带有Jimp.js 的承诺异步加载一堆资源。加载代码试图将其全部链接起来是一场灾难,我需要一个更简洁的解决方案。

我想出的是下面。这显然没有任何作用,因为它是垃圾代码,但我需要知道加载任何资源是否失败,并且我需要知道它们何时完成。

function doSomething(asdf) {
  return new Promise((resolve, reject) => {
    //console.log("It is done.");
    // Succeed half of the time.
    var x = Math.random();    
    if (x > .5) {
      resolve(["SUCCESS",asdf,x])
    } else {
      reject(["Failure",asdf,x])
    }
  });
}



func();

function func() {
    //Imagine a is actually an image loaded by doSomething
    var a=null;  doSomething("1").then(function (data) {a = data;},
            (err) => {throw new err;});
    //Imagine b is a font resource.
    var b=null;  doSomething("2").then(function (data) {b = data;},
            (err) => {throw new err;});

    Promise.all([a, b]).then(function() {
            console.log(a);
            console.log(b);
            //Then here I expect everything to be correct, and continue on with the next function.
    }, 
    (err) => {console.log('Oops:' + err);}).
     catch( (err) => {console.log('Oops:' + err);});
}

由于某种原因,这永远不会输出 “糟糕”

这是一个失败的输出:

['成功','1',0.756461151774289] 空

我在这里错过了什么?

更新

我接受了我收到的答案的一部分并对其进行了更改,以使其完全符合我的要求:

function func() {
    var a=doSomething("1").then(function (data) {a = data;});
    var b=doSomething("2").then(function (data) {b = data;});

    Promise.all([a, b]).then(function() {
            console.log(a);
            console.log(b);
    }, 
    (err) => {console.log('Reject:' + err);});
}

更新

这是我正在使用的实际代码,现在运行良好:

LoadResources() {
    var ps = [];
    console.log("Loading now");

    ps.push(jimp.read(this.ipath+"c4box.png").then(function (image) {obj.imBox = image;}));
    ps.push(jimp.read(this.ipath+"red.png").then(function (image) {obj.imRed = image;}));
    ps.push(jimp.read(this.ipath+"green.png").then(function (image) {obj.imGreen = image;}));
    ps.push(jimp.read(this.ipath+"top.png").then(function (image) {obj.imTop = image;}));
    ps.push(jimp.read(this.ipath+"bot.png").then(function (image) {obj.imBot = image;}));
    ps.push(jimp.loadFont(jimp.FONT_SANS_32_WHITE).then(function (font) {obj.imFont = font;}));

    Promise.all(ps).then( () => {
            obj.loaded = true;
            obj.imBg = new jimp(512, 576, function (err, image) { });
            console.log("Actually loaded now.");                       
            obj.StartGame();
    });
    console.log("Loading commands complete");            
    }

【问题讨论】:

    标签: javascript arrays promise


    【解决方案1】:

    您不能将这些 ab 变量用于图像。 (有关将传递给 Promise.all 的值,请参阅 here)。您需要为doSomething() 返回的承诺对象使用变量。图片将仅在 then 回调中可用 - Promise.all 创建一个通过结果数组实现的承诺:

    function func() {
        // aPromise is a promise for an image loaded by doSomething
        var aPromise = doSomething("1");
        // bPromise is a promise for a font resource.
        var bPromise = doSomething("2");
    
        Promise.all([aPromise, bPromise]).then(function([a, b]) {
    //                                                  ^^^^^^
            console.log(a);
            console.log(b);
            // Then here I expect everything to be correct, and continue on with the next function.
        }, (err) => {
            console.log('Oops:' + err);})
        });
    }
    

    【讨论】:

    • 另外,如果需要格式化数据,或者只需要提取特定部分,您可以在.doSomething() 调用中保留.then(),例如:aPromise = doSomething("1").then(function (data) { return data.subData; }。重要的部分是.then() 中的return 语句,所以它可以继续被链接
    • 谢谢,我把它改成了 var a = doSomething()... 它很完美。我会为将来更新问题。
    • @CharlesW 不,不要使用.then(function (data) {a = data;});
    • 我这样做的原因是 ab 是用于存储图像以供以后使用的类变量。这是 node.js 中的一个持久项目。你能进一步解释为什么我不应该吗?
    • @CharlesW 这些变量是无用的,因为你永远不知道什么时候可以使用它们(如果承诺还没有实现)。相反,将 Promise 对象本身存储在您的类实例中。
    【解决方案2】:
      Promise.all([a, b])
    

    因为 abnull,因为您将它们设置为 null。因此 Promise.all 根本不会等待,它会在之后解决一个滴答声,并且ab 得到解决/拒绝非常快,这可能以前发生过,a / b 之前设置它达到了

     console.log(a)
    

    这将记录正确的结果有时,但那是基于机会。

    【讨论】:

      【解决方案3】:

      Promise.all返回一个promise,这个promise包含之前promise的结果

      Promise.all([ doSomething('1'), doSomething('2')])
        .then(results => {
          // results is an array which contains the result of the previous promises
          const [a, b] = results
        }).catch(err => console.log('Oops:' + err))
      

      【讨论】:

        猜你喜欢
        • 2021-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-21
        • 2018-06-27
        • 2021-10-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多