Увеличение размера кучи не является «исправлением», это «штукатурка», 100% временная. Он снова рухнет в другом месте. Чтобы избежать этих проблем, напишите код высокой производительности.
Кажется, что не существует решения, кроме описанного в вопросе обходного пути. Для дальнейшего использования, если вы хотите выполнить (а не разрешить) обещание p
со значением val
, где val
- другое обещание, а затем просто вызвать функцию разрешения обещаний для p
с аргументом val
не будет работать должным образом. Это заставило бы p
быть «заблокировано» в состоянии val
, так что p
будет выполняться с значением разрешения val
после выполнения val
(см. spec ).
Вместо этого оберните val
в другой объект и разрешите p
с этим объектом:
var resolveP; // Promise resolution function for p
var p = new Promise(
function(resolve, reject) {
resolveP = resolve;
}
);
function fulfillPwithPromise(val) { // Fulfills p with a promise val
resolveP({promise: val});
}
p.then(function(res) {
// Do something as soon as p is fulfilled...
return res.promise;
}).then(function(res) {
// Do something as soon as the second promise is fulfilled...
});
Это решение работает, если вы уже знаете, что val
это обещание. Если вы не можете делать какие-либо предположения о типе val
, вам кажется, что вам не повезло. Либо вы должны всегда переносить значения разрешения обещания в другой объект, либо вы можете попытаться определить, имеет ли val
поле then
типа «функция» и обертывает его условно.
Тем не менее, в некоторых случаях поведение по обещанию по умолчанию может фактически иметь желаемый эффект. Поэтому используйте только описанное выше обходное решение, если вы уверены, что хотите выполнить вместо разрешить первое обещание со вторым.
Нашел аналогичное решение в процессе перехода от $ q в угловую функцию Promise. Promise.all
может быть вариантом (в случае независимых параллельных асинхронных задач) путем передачи вокруг соответствующего объекта или чего-то, украшенного состоянием, передавая его на все, что будет готово, когда это необходимо. В приведенном ниже примере Promise.all обратите внимание на то, как он восстанавливается в одном из обещаний - мне потребовалось некоторое время, чтобы понять, как перенаправить результат цепочки. Результат всего лишь возвращение последнего обещания. Хотя это не отвечает на заголовок вопроса, использование return Promise.reject(<an-object-including-a-promise>)
(или разрешения) дает серию и / или группу асинхронных задач совместного доступа и управления на этом пути. В случае выбора, загрузив, затем работая с файлом, я бы обработал обработку событий прогресса: pickFile.then(download,orFailGracefully)
с downloadProgress
, обработанным в обработчике download
onResolve (процесс загрузки не кажется асинхронная задача). Ниже приведены связанные эксперименты в консоли.
var q = {
defer: function _defer(){
var deferred = { };
deferred.promise = new Promise(function(resolve, reject){
deferred.resolve = resolve;
deferred.reject = reject;
});
return deferred;
}
};
var communityThatCares = q.defer();
communityThatCares.promise.then(function(someGood){
console.log('someGood', someGood);
return someGood;
}, function(someBad){
console.warn('someBad', someBad);
return someBad;
});
(new Promise(function(resolve, reject){ communityThatCares.about = 'communityThatCares'; setTimeout(resolve,1000, communityThatCares); }))
.then(
function(e){
console.log(3,e); return e.resolve(e);
}, function(e){
console.warn(3, e); return e.reject(e);
});
var todo = {
find:'swan'
};
var greaterGood = [(
(new Promise(function(res,rej){ res(todo); })).then(function(e){ e.stuff = 'things'; return e; }),
(new Promise(function(res,reject){
reject(todo);
})).then(function(e){ return e; }
,function(e){
console.warn(1,e);
e.recover = 'uh oh';
return Promise.resolve(e);
}).then(function(e){ console.log(2,e); return e; }),
(new Promise(function(res,rej){ res(todo); })).then(function(e){ console.log(1,e); e.schedule = 'today'; return e; },function(e){ console.warn(1,e); return e; }).then(function(e){ console.log(2,e); return e; }))
];
var nkay = Promise.all( greaterGood )
.then(function(todo){
console.log('all',todo[0]); return todo;
}, function(todo){
console.warn('all',todo[0]); return todo;
});
Хотя разные люди используют разные термины, в общей терминологии, «выполнить» означает пообещать в «успешном» состоянии (в отличие от «отклонения») - состояние, которое будет запускать тогда обработчики then
, свисающие это.
Другими словами, вы не можете «выполнить» обещание с обещанием. Вы можете выполнить его со значением. (Кстати, термин «разрешение» обычно означает либо выполнение, либо отклонение.)
. Что вы можете сделать, это вернуть обещание от обработчика .then
и это будет иметь эффект по существу заменяя оригинальное обещание возвращенным обещанием.
Вот простой пример:
asyncTask1 . then(asyncTask2) . then(processData)
, где asyncTask1
является обещанием, а asyncTask2
- функцией, которая возвращает обещание. Поэтому, когда asyncTask1
выполняется (выполнено успешно), выполняется asyncTask2
, и обещание, возвращенное .then
, «отменено» по обещанию asyncTask2
, возвращается, так что, когда оно заканчивается, данные могут быть обработан.
Я могу сделать что-то подобное, вызвав Promise.resolve
с обещанием в качестве параметра. Это немного неправильно, потому что я не разрешаю обещание в техническом смысле. Вместо этого появившееся новое обещание «заселено» обещанием, в которое я прошел. Это также бесполезно, потому что использование результата точно так же, как использование обещания, которое я прошел:
Promise.resolve(asyncTask2)
ведет себя точно так же как
asyncTask2
(предполагая, что asyncTask2 уже является обещанием, в противном случае Promise.resolve
имеет эффект создания обещания, которое немедленно выполняется с переданным значением.)
Просто поскольку вы можете сдать обещание Promise.resolve
, вы можете передать обещание функции resolve
, предоставленной вам в качестве параметра обратного вызова конструктора обещаний. Если параметр, который вы переходите на resolve
, не обещает, обещание немедленно соответствует этому значению. Однако, если параметр, который вы переходите на resolve
, является другим обещанием, это обещание «берет на себя тело» обещания, которое вы строите. Иными словами, обещание, которое вы строите, начинает вести себя точно так же, как обещание, переданное resolve
.
Под «вести себя точно» я имею в виду, если обещание, которое вы передаете resolve
уже выполнено, обещание, которое вы строите, мгновенно выполняется с одинаковым значением. Если обещание, которое вы перешли к resolve
, уже отклонено, обещание, которое вы строите, немедленно отклоняется по той же причине. Если обещание, которое вы передаете в resolve
, еще не разрешено, тогда любые обработчики then
, в которых вы выполняете обещание, которое вы строите, будут вызваны, если и когда будет достигнуто обещание, которое вы переходите на resolve
.
Так же, как это сбивает с толку, что Promise.resolve
может привести к обещанию, которое на самом деле не разрешено, аналогично сбивает с толку, что вызов функции resolve
, переданный вам в качестве параметра конструктору обещаний, может фактически не решить обещание если вы называете это нерешенным обещанием. Вместо этого, как я уже говорил пару раз, это приводит к тому, что обещание строится в состоянии полной конгруэнтности с обещанием, переданным resolve
.
Поэтому, если я не Отсутствие точки вашего вопроса, pickfile
может быть записано как
function pickFile() {
return new Promise(function(resolve, reject) {
...display the file picker...
// Mock code to pretend the user picked a file
window.setTimeout(function() {
resolve('thefile');
});
}
Я не очень четко понял ваш вопрос, так что это может быть не то, что вы хотите. Просьба уточнить, если вы хотите.
resolve
названа правильно, поскольку спецификация заявляет: «Обещание разрешается, если оно разрешено или если оно« заблокировано », чтобы соответствовать состоянию другого обещания. & Quot; (где «установленный» означает «выполненный или отклоненный»).
– robamler
30 August 2015 в 18:44
pickFile
, но я все еще хочу выполнить обещание, которое возвращается pickFile
сразу после того, как пользователь выбрал файл (загрузка должна продолжаться в фон).
– robamler
30 August 2015 в 18:44
Promise
s. К счастью, патч прост. – ftor 29 March 2018 в 08:20