Может ли promises иметь несколько аргументов для onFulfilled?
Я следую спецификации здесь, и я не уверен, разрешает ли он называть Fulfilled несколько аргументов. Например:
promise = new Promise(function(onFulfilled, onRejected){
onFulfilled('arg1', 'arg2');
})
чтобы мой код:
promise.then(function(arg1, arg2){
// ....
});
получит как arg1
, так и arg2
?
Мне все равно, как это делает какая-либо конкретная реализация promises, я хочу внимательно следить за спецификацией w3c для promises.
Ответы
Ответ 1
Я слежу за спецификацией здесь, и я не уверен, разрешает ли он называть Fulfilled несколько аргументов.
Нет, только первый параметр будет рассматриваться как значение разрешения в конструкторе обещаний. Вы можете разрешить с помощью составного значения, например, объекта или массива.
Меня не волнует, как это делает реализация конкретных обещаний, я хочу внимательно следить за спецификацией w3c для обещаний.
Вот где я считаю, что вы ошибаетесь. Спецификация разработана как минимальная и предназначена для взаимодействия между библиотеками обещаний. Идея состоит в том, чтобы иметь подмножество, которое DOM-фьючерсы, например, могут надежно использоваться, и библиотеки могут потреблять. Реализации обещаний делают то, что вы задаете с помощью .spread
какое-то время. Например:
<Предварительно > <код > Promise.try(функция() { return [ "Hello" , "World" , "!" ];
}). Спрэд (функция (а, б, в) { console.log(а, б + с);// "Привет мир!";
});
Код > С Bluebird. Одно решение, если вы хотите эту функциональность, - polyfill.
if (! Promise.prototype.spread) { Promise.prototype.spread = function (fn) { return this.then(function (args) { return Promise.all(args);//ждать всех }). (то функция (арг) { // это всегда не определено в жалобе A +, но на всякий случай return fn.apply(это, args); }); };
}
Код>
Это позволяет:
<Предварительно > <код > Promise.resolve(нуль).then(функция() { return [ "Hello" , "World" , "!" ];
}). Спрэд (функция (а, б, в) { console.log(а, б + с);
});
Код > С собственными обещаниями в покое скрипка. Или используйте распространение, которое теперь (2018) является обычным явлением в браузерах:
Promise.resolve([ "Hello" , "World" , "!" ]), затем (([a, b, c]) = > { console.log(а, б + с);
});
Код>
Или с ожиданием:
let [a, b, c] = ждать Promise.resolve(['hello', 'world', '!']);
Код>
Ответ 2
Вы можете использовать деструктурирование E6:
Деструктурирование объектов:
promise = new Promise(function(onFulfilled, onRejected){
onFulfilled({arg1: value1, arg2: value2});
})
promise.then(({arg1, arg2}) => {
// ....
});
Деструктурирование массива:
promise = new Promise(function(onFulfilled, onRejected){
onFulfilled([value1, value2]);
})
promise.then(([arg1, arg2]) => {
// ....
});
Ответ 3
Значение выполнения обещания параллельно с возвращаемым значением функции и причиной отклонения обещания параллелируется исключенному исключению функции. Функции не могут возвращать несколько значений, поэтому promises не должно иметь более одного значения выполнения.
Ответ 4
Насколько я могу судить, прочитав спецификацию ES6 Promise и стандартная спецификация обещания. Предложение не предусматривает предотвращение реализации от этого случая - однако оно не реализовано в следующих библиотеках:
Я предполагаю, что причина, по которой они опускают multi arg, заключается в том, чтобы сделать порядок изменения более кратким (то есть, поскольку вы можете вернуть только одно значение в функцию, которая сделает поток управления менее интуитивным). Пример:
new Promise(function(resolve, reject) {
return resolve(5, 4);
})
.then(function(x,y) {
console.log(y);
return x; //we can only return 1 value here so the next then will only have 1 argument
})
.then(function(x,y) {
console.log(y);
});
Ответ 5
Я ищу одно и то же решение и нашел очень интересное из этого ответа: Отклонить promises с несколькими аргументами (например, $http) в AngularJS
ответ этого парня Florian
promise = deferred.promise
promise.success = (fn) ->
promise.then (data) ->
fn(data.payload, data.status, {additional: 42})
return promise
promise.error = (fn) ->
promise.then null, (err) ->
fn(err)
return promise
return promise
И использовать его:
service.get().success (arg1, arg2, arg3) ->
# => arg1 is data.payload, arg2 is data.status, arg3 is the additional object
service.get().error (err) ->
# => err
Ответ 6
У меня была такая же проблема, и я решил это, добавив заголовок в службу
@Provider
public class CORSFilter implements ContainerResponseFilter {
@Override
public void filter(final ContainerRequestContext requestContext,
final ContainerResponseContext cres) throws IOException {
cres.getHeaders().add("Access-Control-Allow-Origin", "*");
cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, Authorization, Authentication");
cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
cres.getHeaders().add("Access-Control-Max-Age", "1209600");
//I just add this header
cres.getHeaders().add("access-control-expose-headers" , "Authorization");
}
}
Ответ 7
Чтобы процитировать приведенную ниже статью, "then" принимает два аргумента, обратный вызов для случая успеха и другой для случая сбоя. Оба являются необязательными, поэтому вы можете добавить обратный вызов только для случая успеха или отказа."
Я обычно смотрю на эту страницу для любых основных вопросов обещания, дайте мне знать, если я ошибаюсь
http://www.html5rocks.com/en/tutorials/es6/promises/
Ответ 8
Так как функции в Javascript можно вызывать с любым количеством аргументов, и в документе не помещается никаких ограничений на аргументы метода onFulfilled(), кроме предложения ниже, я думаю, что вы можете передать несколько аргументов в onFulfilled() метод, если значение обещания является первым аргументом.
2.2.2.1 it must be called after promise is fulfilled, with promise’s value as its first argument.
Ответ 9
Великий вопрос и большой ответ Бенджамина, Криса и др. - большое спасибо!
Я использую это в проекте и создал модуль на основе кода Бенджамина Грюнвальда. Он доступен на npmjs:
npm i -S promise-spread
Затем в вашем коде сделайте
require('promise-spread');
Если вы используете библиотеку, например any-promise
var Promise = require('any-promise');
require('promise-spread')(Promise);
Возможно, другие считают это полезным тоже!