Ваш вопрос имеет некоторые проблемы:
- Переменная
r2
нигде не определена. Я предполагаю, result
был предназначен.
-
setTimeout
не делает ничего полезного, так как вы выполняете result(2)
немедленно. Я предполагаю, что setTimeout(() => result(2), 500)
было задумано.
Если код был действительно задан таким образом на собеседовании, тогда ваша задача - указать на эти две проблемы, прежде чем делать что-либо еще.
Одна проблема с вашей попыткой состоит в том, что обещание, возвращаемое методом then
(т. Е. result
), никогда не разрешается. Вам необходимо разрешить его, как только будет выполнено обещание this
со значением, возвращаемым обратным вызовом then
.
Кроме того, аргумент конструктора обещаний - это функция, которая должна выполняться немедленно.
В следующем решении сделано несколько упрощений по сравнению с правильным поведением Promise.
- Не вызывает асинхронные обратные вызовы
then
;
- Он не поддерживает несколько вызовов
then
для одного и того же обещания;
- Это не обеспечивает путь отклонения;
- Это не мешает выполнению обещания дважды с другим значением;
- Это не касается особого случая, когда
then
обратный вызов возвращает обещание
console.log("Wait for it...");
class MyPromise {
constructor(executor) {
executor(result => this.resolve(result));
}
resolve(value) {
this.value = value;
this.broadcast();
}
then(onFulfilled) {
const promise = new MyPromise(() => null);
this.onFulfilled = onFulfilled;
this.resolver = (result) => promise.resolve(result);
this.broadcast();
return promise;
}
broadcast() {
if (this.onFulfilled && "value" in this) this.resolver(this.onFulfilled(this.value));
}
};
// Code provided by interviewer, including two corrections
promise = new MyPromise(
(result) => {
setTimeout(()=>result(2), 500); // don't execute result(2) immediately
});
promise.then(result => {
console.log(result); // Changed r2 to result.
return 2 * result;
}).then(result => console.log(result));
Обратите внимание, что задержка на выходе составляет 500 мс, что и следует ожидать от (исправленного) кода setTimeout
.
Я разместил полную реализацию обещаний, совместимых с Promises / A +, с комментариями в этот ответ