JavaScript и Promise.all () - PullRequest
       9

JavaScript и Promise.all ()

0 голосов
/ 02 мая 2018

Я пытаюсь загрузить кучу ресурсов асинхронно, используя обещания с 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");            
    }

Ответы [ 3 ]

0 голосов
/ 02 мая 2018
  Promise.all([a, b])

Причина a и b равны null, если вы установите их на null. Поэтому Promise.all вообще не будет ждать, он разрешит один тик впоследствии, и когда a и b будут решены / отклонены очень быстро, что могло случиться раньше, и a / b устанавливается раньше оно достигает

 console.log(a)

, который будет регистрировать правильные результаты иногда , но это зависит от случая.

0 голосов
/ 02 мая 2018

Promise.all возвращает обещание, и это обещание содержит результат предыдущих обещаний

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))
0 голосов
/ 02 мая 2018

Вы не можете использовать эти a и b переменные для изображений. (См. здесь для значений, которые будут переданы в Promise.all). Вам необходимо использовать переменные для объектов обещания, которые 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);})
    });
}
...