Может ли 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);

Возможно, другие считают это полезным тоже!