2015-07-08 2 views
2

Я начал diggin 'в обещаниях и нашел интересный Promise.all.Как работает обещание.

Об этом говорится в MDN, что

Promise.all (итерация) метод возвращает обещание, которое решает, когда все обещания в итерации аргумента разрешил.

Что в основном означает, что заданные обещания решаются после, и если все обещания в списке аргументов были разрешены. Я попытался его реализовать. Я просто обещал ajax-вызов.

var get = function(url) { 
    return new Promise(function(resolve,reject) { 
     var xhtml=new XMLHttpRequest(); 

     xhtml.open("GET",url); 
     xhtml.responseType = 'blob'; 
     xhtml.onload = function() { 
      if(xhtml.status==200){ 
       resolve(xhtml.response); 
      } else { 
       reject(Error("Error"+statusText)); 
      } 
     } 
     xhtml.send(); 
    }); 

} 

get("one.jpg").then(function(response){ 
    var blob = window.URL.createObjectURL(response); 
    var img = document.createElement("img"); 

    console.log("Success"+response); 

    img.src = blob; 

    document.body.appendChild(img); 
}); 

Который работает хорошо. Но после того, как я попытался добавить Promise.all, он сделал ошибку.

Promise.all(get).then(function(response){alert("done")}); 

это как я сказал, бросали ошибку «аргумент 1 из Promise.all не может быть преобразован в последовательность.» Так что я предполагаю, что я не понял смысл обещания. Как это работает?

+4

'get' - это функция; 'Promise.all()' принимает массив объектов с обещаниями –

ответ

3

Функция get возвращает Promise. Вы просто передаете ссылку на функцию get. Вы должны передать массив Promises

Promise.all([get("one.jpg")]).then(...); 
4

Promise.all принимает массив (или какой-либо итерацию) обещаний и выполняет, когда все они выполняют или отвергает, когда один из них отказывается. Я думаю, что это легче понять, если мы его реализуем и понимаем, зачем нам это нужно.

Общий случай использования может быть ждать окна для загрузки и для сервера, чтобы вернуть данные для того, чтобы запустить код:

// a function that returns a promise for when the document is ready. 
function windowReady(){ 
    return new Promise(function(resolve){ 
     window.addEventListener('DOMContentLoaded', resolve); 
    }); 
} 

// function that returns a promise for some data 
function getData(){ 
    return fetch("/").then(function(r){ return r.json() }); 
} 

Теперь мы хотим, чтобы оба из них, чтобы выполнить на то же время, а затем получите результат. Есть два пункта здесь, но могло бы легко было 5 вещей ждут, или 100. Таким образом, мы используем Promise.all:

Promise.all([windowReady(), getData()]).then(function(results){ 
    // results[1] is the data, it's all in an array. 
}); 

Давайте посмотрим, как мы можем реализовать:

function all(iterable){ // take an iterable 
    // `all` returns a promise. 
    return new Promise(function(resolve, reject){ 
    let counter = 0; // start with 0 things to wait for 
    let results = [], i; 
    for(let p of iterable){ 
     let current = i; 
     counter++; // increase the counter 
     Promise.resolve(p).then(function(res){ // treat p as a promise, when it is ready: 
      results[i] = res; // keep the current result 
      if(counter === 0) resolve(results) // we're done 
     }, reject); // we reject on ANY error 
     i++; // progress counter for results array 
    } 
    }); 
} 

Или, еще больше ES6ness:

let all = iterable => new Promise((resolve, reject) => { 
    let arr = [...iterable], c = arr.length, results = []; 
    arr.map(Promise.resolve, Promise). 
     map((p, i) => p.then(v => { 
     r[i] = v; 
     if(--c === 0) resolve(r); 
     } , reject)); 
}); 
+0

Объяснение объяснения, спасибо !. Но я не уверен, есть ли у меня мало вещей. 1) Здесь Promise.resolve (p). Then (function (res) «обрабатывать p как обещание», я предполагаю, что здесь будет передан non prosime. Какой средний аргумент в обратном вызове будет возвращен p, но что, если мы обещал ли там что-то, что тогда будет передано?) 2) в windowReady вы передали решение как функцию в eventListener без аргумента, im не уверен, что вы хотели сказать с этим. Спасибо за ответ! – Darlyn

Смежные вопросы