Skip to content

Commit

Permalink
Update: Finish IteratorClose()
Browse files Browse the repository at this point in the history
  • Loading branch information
nzakas committed Nov 18, 2020
1 parent 42f2782 commit 0358b08
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 10 deletions.
67 changes: 59 additions & 8 deletions src/pledge.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import {
PledgeAggregateError,
iteratorStep,
iteratorValue,
getIterator
getIterator,
iteratorClose,
ThrowCompletion
} from "./utilities.js";
import {
isPledge,
Expand Down Expand Up @@ -98,14 +100,22 @@ export class Pledge {

const C = this;
const pledgeCapability = new PledgeCapability(C);
let iteratorRecord;

try {
const pledgeResolve = getPledgeResolve(C);
const iteratorRecord = getIterator(iterable);
iteratorRecord = getIterator(iterable);
const result = performPledgeAny(iteratorRecord, C, pledgeCapability, pledgeResolve);
return result;
} catch (error) {
pledgeCapability.reject(error);

let result = new ThrowCompletion(error);

if (iteratorRecord && iteratorRecord.done === false) {
result = iteratorClose(iteratorRecord, result);
}

pledgeCapability.reject(result.value);
return pledgeCapability.pledge;
}
}
Expand All @@ -114,14 +124,22 @@ export class Pledge {

const C = this;
const pledgeCapability = new PledgeCapability(C);
let iteratorRecord;

try {
const pledgeResolve = getPledgeResolve(C);
const iteratorRecord = getIterator(iterable);
iteratorRecord = getIterator(iterable);
const result = performPledgeRace(iteratorRecord, C, pledgeCapability, pledgeResolve);
return result;
} catch (error) {
pledgeCapability.reject(error);

let result = new ThrowCompletion(error);

if (iteratorRecord && iteratorRecord.done === false) {
result = iteratorClose(iteratorRecord, result);
}

pledgeCapability.reject(result.value);
return pledgeCapability.pledge;
}

Expand All @@ -131,15 +149,49 @@ export class Pledge {

const C = this;
const pledgeCapability = new PledgeCapability(C);
let iteratorRecord;

try {
const pledgeResolve = getPledgeResolve(C);
const iteratorRecord = getIterator(iterable);
iteratorRecord = getIterator(iterable);
const result = performPledgeAll(iteratorRecord, C, pledgeCapability, pledgeResolve);
return result;
} catch (error) {
pledgeCapability.reject(error);

let result = new ThrowCompletion(error);

if (iteratorRecord && iteratorRecord.done === false) {
result = iteratorClose(iteratorRecord, result);
}

pledgeCapability.reject(result.value);
return pledgeCapability.pledge;
}

}

static allSettled(iterable) {

const C = this;
const pledgeCapability = new PledgeCapability(C);
let iteratorRecord;

try {
const pledgeResolve = getPledgeResolve(C);
iteratorRecord = getIterator(iterable);
// const result = performPledgeAllSettled(iteratorRecord, C, pledgeCapability, pledgeResolve);
// return result;
} catch (error) {

let result = new ThrowCompletion(error);

if (iteratorRecord && iteratorRecord.done === false) {
result = iteratorClose(iteratorRecord, result);
}

pledgeCapability.reject(result.value);
return pledgeCapability.pledge;

}

}
Expand Down Expand Up @@ -315,7 +367,6 @@ function getPledgeResolve(pledgeConstructor) {

function performPledgeAll(iteratorRecord, constructor, resultCapability, pledgeResolve) {


assertIsConstructor(constructor);
assertIsCallable(pledgeResolve);

Expand Down
82 changes: 82 additions & 0 deletions src/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,34 @@ export function PledgeAggregateError(errors=[], message) {
return O;
}

//-----------------------------------------------------------------------------
// 7.3.10 GetMethod(V, P)
//-----------------------------------------------------------------------------

/*
* This method is only used in `iteratorClose()` for better adhering to the
* spec. This really just returns a method with a given name from a given
* object, but we need the completion record to be returned so the
* `iteratorClose()` function makes sense.
*/
function getMethod(V, P) {

if (!(P in V)) {
return new ThrowCompletion(new TypeError("Property not found."));
}

let func = V[P];
if (func === undefined || func === null) {
return new NormalCompletion(undefined);
}

if (isCallable(func) === false) {
return new ThrowCompletion(new TypeError("Property is not a method."));
}

return new NormalCompletion(func);
}

//-----------------------------------------------------------------------------
// 7.4.1 GetIterator ( obj [ , hint [ , method ] ] )
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -199,3 +227,57 @@ export function iteratorStep(iteratorRecord) {

return result;
}

//-----------------------------------------------------------------------------
// 7.4.6 IteratorClose ( iteratorRecord, completion )
//-----------------------------------------------------------------------------

/*
* The primary purpose of this function is just to close out an iterator that
* might not have finished due to an error.
*/
export function iteratorClose(iteratorRecord, completion) {

if (!isObject(iteratorRecord.iterator)) {
throw new TypeError("Iterator must be an object.");
}

const iterator = iteratorRecord.iterator;

let innerResult = getMethod(iterator, "return");

/*
* In the spec, this is `return`, but we can't use that in JavaScript
* because `return` is a keyword.
*/
let returnFunction;

if (innerResult.type === "normal") {
returnFunction = innerResult.value;

if (returnFunction === undefined) {
return completion;
}

try {
innerResult = new NormalCompletion(returnFunction.call(iterator));
} catch (error) {
innerResult = new ThrowCompletion(error);
}

}

if (completion.type === "throw") {
return completion;
}

if (innerResult.type === "throw") {
return innerResult;
}

if (!isObject(innerResult.value)) {
return new ThrowCompletion(new TypeError("Error isn't an object."));
}

return completion;
}
2 changes: 0 additions & 2 deletions tests/pledge.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,6 @@ describe("Pledge", () => {
});
});



it("should return the first value that was resolved", done => {

const pledge = Pledge.race([
Expand Down

0 comments on commit 0358b08

Please sign in to comment.