Promise.settle Bluebird не разрешается с правильными значениями

У меня есть следующий код:

return Promise.settle(matches, imgur.uploadUrl)
    .map(function (inspection) {
        if (inspection.isFulfilled()) {
            return inspection.value().data.link;
        }
        return '#';
    })

Более подробная версия приведенного выше показывает те же проблемы:

return Promise.settle(matches, function(match) { return imgur.uploadUrl(match); })
    .then(function(results) {
        return results;
    })
    .map(function (inspection) {
        if (inspection.isFulfilled()) {
            return inspection.value().data.link;
        }
        return '#';
    })

Где

  • Promise = обещание синей птицы
  • matches = массив ссылок на изображения, извлеченный из строки
  • imgur = https://github.com/kaimallea/node-imgur

Ожидаемое поведение заключается в том, что результатом .map является обещание, которое разрешается с помощью массива ссылок imgur после того, как изображения в исходном массиве были загружены в imgur (или «#», если загрузка по какой-либо причине не удалась).

Вместо этого происходит то, что Promise.settle разрешается мгновенно (т. е. не ждет загрузки imgur), а inspection.value() — это исходный URL-адрес изображения из массива matches (который выдает ошибку при попытке прочитать свойство .data.link строки).

Почему это происходит? Почему он не загружается в imgur и не разрешается правильно?


person Madara's Ghost    schedule 27.10.2014    source источник
comment
Я бы предложил сначала упростить до Promise.settle(matches, imgur.uploadUrl).then(function(results) { ... }), чтобы увидеть, содержит ли results то, что вы ожидаете, чтобы вы могли видеть, делает ли это .settle() не то, что вы хотите, или .map().   -  person jfriend00    schedule 27.10.2014
comment
Я действительно сделал это до того, как добрался до этой точной версии кода, и это не имело большого значения.   -  person Madara's Ghost    schedule 27.10.2014
comment
Цель моего комментария заключалась в том, чтобы вы объяснили, дает ли только .settle() правильные результаты или нет? Проблема с .settle() или с .map(). Я пытаюсь разбить сложную проблему на части, чтобы каждый знал, где искать проблему дальше.   -  person jfriend00    schedule 27.10.2014
comment
Когда я смотрю на исходный код Bluebird для Promise.settle(), я вижу только посмотрите, что он обрабатывает первый аргумент (ожидая массив промисов). Интересно, не ошиблась ли документация Bluebird для .settle() в том, что она принимает функцию в качестве второго аргумента, которая будет обрабатывать первый массив? Код немного сложен для понимания, но я не понимаю, как Promise.settle() когда-либо использует второй аргумент (если только это не тот код, на который я смотрю по какой-то причине).   -  person jfriend00    schedule 27.10.2014
comment
@jfriend00 Опубликуйте это как ответ. Я провел рефакторинг на Promise.settle(matches.map(imgur.uploadUrl)), и это сработало. Я зарегистрирую ошибку с помощью bluebird   -  person Madara's Ghost    schedule 27.10.2014


Ответы (2)


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

Интересно, не ошибается ли документация Bluebird для .settle() в том, что она принимает функцию в качестве второго аргумента, которая будет обрабатывать первый массив? Код немного сложен для понимания, но я не понимаю, как Promise.settle() когда-либо использует второй аргумент (если только это не тот код, на который я смотрю по какой-то причине).

Как вы указали, альтернатива:

Promise.settle(matches.map(imgur.uploadUrl)).then(...)

который просто передает массив обещаний в .settle().


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

person jfriend00    schedule 27.10.2014

Это действительно была ошибка в документах. Это было исправлено (реквизит OP для запроса на включение).

Документы теперь показывают правильное использование .settle.

person Benjamin Gruenbaum    schedule 27.10.2014
comment
@andig да, новый способ 3.0 - это .reflect. - person Benjamin Gruenbaum; 04.11.2015
comment
Как сказал @andig, reflect не существует в Bluebird v3.0.5, но settle, похоже, работает. - person rbarriuso; 08.12.2015
comment
@rbarriuso Reflect наверняка существует в 3.x - person Benjamin Gruenbaum; 08.12.2015
comment
Истинный. Reflect - это новое решение! - person andig; 09.12.2015